40f6e93c0f0d29b94a6fbc3858016aa530f82055
[platform/core/appfw/badge.git] / src / badge_internal.c
1 /*
2  * Copyright (c) 2000 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
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
18 #include <string.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <glib.h>
24 #include <gio/gio.h>
25 #include <dbus/dbus.h>
26 #include <dbus/dbus-glib-lowlevel.h>
27 #include <aul.h>
28 #include <sqlite3.h>
29 #include <db-util.h>
30 #include <package_manager.h>
31 #include <tzplatform_config.h>
32 #include <sys/smack.h>
33
34 #include "badge_log.h"
35 #include "badge_error.h"
36 #include "badge_internal.h"
37 #include "badge_ipc.h"
38 #include "badge_db.h"
39
40 #define BADGE_PKGNAME_LEN 512
41 #define BADGE_TABLE_NAME "badge_data"
42 #define BADGE_OPTION_TABLE_NAME "badge_option"
43
44 #define BADGE_CHANGED_NOTI      "badge_changed"
45
46 struct _badge_h {
47         char *pkgname;
48         char *writable_pkgs;
49 };
50
51 struct _badge_cb_data {
52         badge_change_cb callback;
53         void *data;
54 };
55
56 static GHashTable *_badge_cb_hash = NULL;
57
58 static inline long _get_max_len(void)
59 {
60         long max = 0;
61         long path_max_len = 4096;
62
63 #ifdef _PC_PATH_MAX
64         max = (pathconf("/", _PC_PATH_MAX) < 1 ? path_max_len
65                                 : pathconf("/", _PC_PATH_MAX));
66 #else /* _PC_PATH_MAX */
67         max = path_max_len;
68 #endif /* _PC_PATH_MAX */
69         return max;
70 }
71
72 char *_badge_get_pkgname_by_pid(void)
73 {
74         char *pkgname = NULL;
75         int pid = 0;
76         int ret = AUL_R_OK;
77         int fd = 0;
78         long max = 0;
79
80         pid = getpid();
81         max = _get_max_len();
82         pkgname = malloc(max);
83         if (!pkgname) {
84                 /* LCOV_EXCL_START */
85                 ERR("fail to alloc memory");
86                 return NULL;
87                 /* LCOV_EXCL_STOP */
88         }
89         memset(pkgname, 0x00, max);
90
91         ret = aul_app_get_pkgname_bypid(pid, pkgname, max);
92         if (ret != AUL_R_OK) {
93                 fd = open("/proc/self/cmdline", O_RDONLY);
94                 if (fd < 0) {
95                         /* LCOV_EXCL_START */
96                         free(pkgname);
97                         return NULL;
98                         /* LCOV_EXCL_STOP */
99                 }
100
101                 ret = read(fd, pkgname, max - 1);
102                 if (ret <= 0) {
103                         /* LCOV_EXCL_START */
104                         close(fd);
105                         free(pkgname);
106                         return NULL;
107                         /* LCOV_EXCL_STOP */
108                 }
109
110                 close(fd);
111         }
112
113         if (pkgname[0] == '\0') {
114                 /* LCOV_EXCL_START */
115                 free(pkgname);
116                 return NULL;
117                 /* LCOV_EXCL_STOP */
118         } else {
119                 return pkgname;
120         }
121 }
122
123 static int _badge_check_data_inserted(const char *pkgname,
124                                         sqlite3 *db, uid_t uid)
125 {
126         sqlite3_stmt *stmt = NULL;
127         int count = 0;
128         int result = BADGE_ERROR_NONE;
129         char *sqlbuf = NULL;
130         int sqlret;
131
132         if (!pkgname)
133                 return BADGE_ERROR_INVALID_PARAMETER;
134
135         if (!db)
136                 return BADGE_ERROR_INVALID_PARAMETER;
137
138         sqlbuf = sqlite3_mprintf("SELECT count(*) FROM %q WHERE " \
139                          "pkgname = %Q AND uid = %d",
140                          BADGE_TABLE_NAME, pkgname, uid);
141
142         if (!sqlbuf) {
143                 /* LCOV_EXCL_START */
144                 ERR("fail to alloc sql query");
145                 return BADGE_ERROR_OUT_OF_MEMORY;
146                 /* LCOV_EXCL_STOP */
147         }
148
149         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
150         if (sqlret != SQLITE_OK) {
151                 /* LCOV_EXCL_START */
152                 ERR("DB err [%s]", sqlite3_errmsg(db));
153                 ERR("query[%s]", sqlbuf);
154                 result = BADGE_ERROR_FROM_DB;
155                 goto free_and_return;
156                 /* LCOV_EXCL_STOP */
157         }
158
159         sqlret = sqlite3_step(stmt);
160         if (sqlret == SQLITE_ROW)
161                 count = sqlite3_column_int(stmt, 0);
162         else
163                 count = 0;
164
165         DBG("[%s], DB search result[%d]", sqlbuf, count);
166
167         if (count > 0)
168                 result = BADGE_ERROR_ALREADY_EXIST;
169         else
170                 result = BADGE_ERROR_NOT_EXIST;
171
172 free_and_return:
173         if (sqlbuf)
174                 sqlite3_free(sqlbuf);
175
176         if (stmt)
177                 sqlite3_finalize(stmt);
178
179         return result;
180 }
181
182 static int _badge_check_option_inserted(const char *pkgname,
183                                         sqlite3 *db, uid_t uid)
184 {
185         sqlite3_stmt *stmt = NULL;
186         int count = 0;
187         int result = BADGE_ERROR_NONE;
188         char *sqlbuf = NULL;
189         int sqlret;
190
191         if (!pkgname)
192                 return BADGE_ERROR_INVALID_PARAMETER;
193
194         if (!db)
195                 return BADGE_ERROR_INVALID_PARAMETER;
196
197         sqlbuf = sqlite3_mprintf("SELECT count(*) FROM %q WHERE " \
198                          "pkgname = %Q AND uid = %d",
199                          BADGE_OPTION_TABLE_NAME, pkgname, uid);
200
201         if (!sqlbuf) {
202                 /* LCOV_EXCL_START */
203                 ERR("fail to alloc sql query");
204                 return BADGE_ERROR_OUT_OF_MEMORY;
205                 /* LCOV_EXCL_STOP */
206         }
207
208         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
209         if (sqlret != SQLITE_OK) {
210                 /* LCOV_EXCL_START */
211                 ERR("DB err [%s]", sqlite3_errmsg(db));
212                 ERR("query[%s]", sqlbuf);
213                 result = BADGE_ERROR_FROM_DB;
214                 goto free_and_return;
215                 /* LCOV_EXCL_STOP */
216         }
217
218         sqlret = sqlite3_step(stmt);
219         if (sqlret == SQLITE_ROW)
220                 count = sqlite3_column_int(stmt, 0);
221         else
222                 count = 0;
223
224         DBG("[%s], DB search result[%d]", sqlbuf, count);
225
226         if (count > 0)
227                 result = BADGE_ERROR_ALREADY_EXIST;
228         else
229                 result = BADGE_ERROR_NOT_EXIST;
230
231 free_and_return:
232         if (sqlbuf)
233                 sqlite3_free(sqlbuf);
234
235         if (stmt)
236                 sqlite3_finalize(stmt);
237
238         return result;
239 }
240
241 static int _is_same_certinfo(const char *caller, const char *pkgname)
242 {
243         int ret = PACKAGE_MANAGER_ERROR_NONE;
244         package_manager_compare_result_type_e compare_result = PACKAGE_MANAGER_COMPARE_MISMATCH;
245
246         if (!caller || !pkgname)
247                 return 0;
248
249         ret = package_manager_compare_package_cert_info(pkgname, caller, &compare_result);
250         if (ret == PACKAGE_MANAGER_ERROR_NONE &&
251                 compare_result == PACKAGE_MANAGER_COMPARE_MATCH)
252                 return 1;
253
254         return 0;
255 }
256
257 static bool __check_label(pid_t pid)
258 {
259 #define SMACK_LABEL_LEN 255
260 #define COMPARE_LABEL_COUNT 3
261
262         bool ret = false;
263         int i;
264         ssize_t len;
265         char *label = NULL;
266         char check_label[COMPARE_LABEL_COUNT][SMACK_LABEL_LEN+1] = { "System", "System::Privileged", "User"};
267
268         len = smack_new_label_from_process(pid, &label);
269         if (len < 0 || label == NULL)
270                 goto out;
271
272         for (i = 0; i < COMPARE_LABEL_COUNT; i++) {
273                 if (g_strcmp0(label, check_label[i]) == 0) {
274                         ret = true;
275                         goto out;
276                 }
277         }
278
279 out:
280         if (label)
281                 free(label);
282
283         return ret;
284 }
285
286 static int _badge_check_writable(const char *caller,
287                         const char *pkgname, sqlite3 *db, uid_t uid, pid_t pid)
288 {
289         sqlite3_stmt *stmt = NULL;
290         int count = 0;
291         int result = BADGE_ERROR_NONE;
292         char *sqlbuf = NULL;
293         int sqlret;
294
295         if (!db || !caller || !pkgname)
296                 return BADGE_ERROR_INVALID_PARAMETER;
297
298         if (g_strcmp0(caller, pkgname) == 0)
299                 return BADGE_ERROR_NONE;
300
301         if (__check_label(pid) == true)
302                 return BADGE_ERROR_NONE;
303
304         /* LCOV_EXCL_START */
305         if (_is_same_certinfo(caller, pkgname) == 1)
306                 return BADGE_ERROR_NONE;
307
308         sqlbuf = sqlite3_mprintf("SELECT COUNT(*) FROM %q WHERE " \
309                          "pkgname = %Q AND writable_pkgs LIKE '%%%q%%'" \
310                          "AND uid = %d",
311                          BADGE_TABLE_NAME,
312                          pkgname, caller, uid);
313         if (!sqlbuf) {
314                 ERR("fail to alloc sql query");
315                 return BADGE_ERROR_OUT_OF_MEMORY;
316         }
317
318         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
319         if (sqlret != SQLITE_OK) {
320                 ERR("DB err [%s]", sqlite3_errmsg(db));
321                 ERR("query[%s]", sqlbuf);
322                 result = BADGE_ERROR_FROM_DB;
323                 goto free_and_return;
324         }
325
326         sqlret = sqlite3_step(stmt);
327         if (sqlret == SQLITE_ROW)
328                 count = sqlite3_column_int(stmt, 0);
329         else
330                 count = 0;
331
332         DBG("[%s], DB search result[%d]", sqlbuf, count);
333
334         if (count <= 0)
335                 result = BADGE_ERROR_PERMISSION_DENIED;
336
337 free_and_return:
338         if (sqlbuf)
339                 sqlite3_free(sqlbuf);
340
341         if (stmt)
342                 sqlite3_finalize(stmt);
343
344         return result;
345         /* LCOV_EXCL_STOP */
346 }
347
348 int _badge_is_existing(const char *pkgname, bool *existing, uid_t uid)
349 {
350         sqlite3 *db = NULL;
351         int sqlret;
352         int result = BADGE_ERROR_NONE;
353
354         if (!pkgname || !existing) {
355                 /* LCOV_EXCL_START */
356                 ERR("pkgname : %s, existing : %p", pkgname, existing);
357                 return BADGE_ERROR_INVALID_PARAMETER;
358                 /* LCOV_EXCL_STOP */
359         }
360
361         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
362         if (sqlret != SQLITE_OK || !db) {
363                 /* LCOV_EXCL_START */
364                 ERR("fail to db_util_open - [%d]", sqlret);
365                 if (sqlret == SQLITE_PERM)
366                         return BADGE_ERROR_PERMISSION_DENIED;
367                 return BADGE_ERROR_FROM_DB;
368                 /* LCOV_EXCL_STOP */
369         }
370
371         result = _badge_check_data_inserted(pkgname, db, uid);
372         if (result == BADGE_ERROR_ALREADY_EXIST) {
373                 *existing = TRUE;
374                 result = BADGE_ERROR_NONE;
375         } else if (result == BADGE_ERROR_NOT_EXIST) {
376                 *existing = FALSE;
377                 result = BADGE_ERROR_NONE;
378         }
379
380         sqlret = db_util_close(db);
381         if (sqlret != SQLITE_OK)
382                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
383
384         return result;
385 }
386
387 int _badge_get_list(GList **badge_list, uid_t uid)
388 {
389         sqlite3 *db = NULL;
390         int result = BADGE_ERROR_NONE;
391         char *sqlbuf = NULL;
392         sqlite3_stmt *stmt = NULL;
393         int sqlret;
394         const char *pkg;
395         unsigned int badge_count;
396         badge_info_s *badge_info;
397
398         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
399         if (sqlret != SQLITE_OK || !db) {
400                 /* LCOV_EXCL_START */
401                 ERR("fail to db_util_open - [%d]", sqlret);
402                 return BADGE_ERROR_FROM_DB;
403                 /* LCOV_EXCL_STOP */
404         }
405
406         sqlbuf = sqlite3_mprintf("SELECT pkgname, badge FROM %q WHERE uid = %d",
407                                 BADGE_TABLE_NAME, uid);
408         if (!sqlbuf) {
409                 /* LCOV_EXCL_START */
410                 ERR("fail to alloc sql query");
411                 result = BADGE_ERROR_OUT_OF_MEMORY;
412                 goto free_and_return;
413                 /* LCOV_EXCL_STOP */
414         }
415
416         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
417         if (sqlret != SQLITE_OK) {
418                 /* LCOV_EXCL_START */
419                 ERR("fail to sqlite3_prepare_v2 - [%s]", sqlite3_errmsg(db));
420                 ERR("query[%s]", sqlbuf);
421                 result = BADGE_ERROR_FROM_DB;
422                 goto free_and_return;
423                 /* LCOV_EXCL_STOP */
424         }
425
426         sqlret = sqlite3_step(stmt);
427         if (sqlret == SQLITE_DONE) {
428                 INFO("badge db has no data");
429                 result = BADGE_ERROR_NOT_EXIST;
430                 goto free_and_return;
431         } else if (sqlret != SQLITE_ROW) {
432                 ERR("fail to sqlite3_step : %d", sqlret);
433                 result = BADGE_ERROR_FROM_DB;
434                 goto free_and_return;
435         }
436
437         do {
438                 pkg = (const char *)sqlite3_column_text(stmt, 0);
439                 badge_count = (unsigned int)sqlite3_column_int(stmt, 1);
440                 if (pkg) {
441                         badge_info = (badge_info_s *)calloc(sizeof(badge_info_s), 1);
442                         if (badge_info == NULL) {
443                                 /* LCOV_EXCL_START */
444                                 ERR("alloc badge_info fail");
445                                 result = BADGE_ERROR_OUT_OF_MEMORY;
446                                 break;
447                                 /* LCOV_EXCL_STOP */
448                         }
449                         badge_info->pkg = strdup(pkg);
450                         badge_info->badge_count = badge_count;
451                         *badge_list = g_list_append(*badge_list, badge_info);
452                 } else {
453                         /* LCOV_EXCL_START */
454                         ERR("db has invaild data");
455                         result = BADGE_ERROR_FROM_DB;
456                         /* LCOV_EXCL_STOP */
457                 }
458         } while (sqlite3_step(stmt) == SQLITE_ROW);
459
460 free_and_return:
461         if (sqlbuf)
462                 sqlite3_free(sqlbuf);
463
464         if (stmt)
465                 sqlite3_finalize(stmt);
466
467         sqlret = db_util_close(db);
468         if (sqlret != SQLITE_OK)
469                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
470
471         return result;
472 }
473
474 int _badge_insert(badge_h *badge, uid_t uid)
475 {
476         sqlite3 *db = NULL;
477         int sqlret;
478         int ret = BADGE_ERROR_NONE;
479         int result = BADGE_ERROR_NONE;
480         char *sqlbuf = NULL;
481
482         if (!badge || !badge->pkgname || !badge->writable_pkgs)
483                 return BADGE_ERROR_INVALID_PARAMETER;
484
485         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
486         if (sqlret != SQLITE_OK || !db) {
487                 /* LCOV_EXCL_START */
488                 ERR("fail to db_util_open - [%s][%d]", BADGE_DB_PATH, sqlret);
489                 return BADGE_ERROR_FROM_DB;
490                 /* LCOV_EXCL_STOP */
491         }
492
493         /* Check pkgname & id */
494         ret = _badge_check_data_inserted(badge->pkgname, db, uid);
495         if (ret != BADGE_ERROR_NOT_EXIST) {
496                 /* LCOV_EXCL_START */
497                 result = ret;
498                 goto return_close_db;
499                 /* LCOV_EXCL_STOP */
500         }
501
502         sqlbuf = sqlite3_mprintf("INSERT INTO %q " \
503                         "(pkgname, " \
504                         "writable_pkgs, " \
505                         "uid) "\
506                         "VALUES " \
507                         "(%Q, %Q, %d);",
508                          BADGE_TABLE_NAME,
509                          badge->pkgname, badge->writable_pkgs, uid);
510         if (!sqlbuf) {
511                 /* LCOV_EXCL_START */
512                 ERR("fail to alloc query");
513                 result = BADGE_ERROR_OUT_OF_MEMORY;
514                 goto return_close_db;
515                 /* LCOV_EXCL_STOP */
516         }
517
518         ret = badge_db_exec(db, sqlbuf, NULL);
519         if (ret != BADGE_ERROR_NONE) {
520                 /* LCOV_EXCL_START */
521                 ERR("failed to insert badge[%s], err[%d]",
522                                         badge->pkgname, ret);
523                 result = ret;
524                 goto return_close_db;
525                 /* LCOV_EXCL_STOP */
526         }
527
528         /* inserting badge options */
529         ret = _badge_check_option_inserted(badge->pkgname, db, uid);
530         if (ret != BADGE_ERROR_NOT_EXIST) {
531                 result = ret;
532                 goto return_close_db;
533         }
534
535         sqlbuf = sqlite3_mprintf("INSERT INTO %q " \
536                         "(pkgname, " \
537                         "uid) " \
538                         "VALUES "
539                         "(%Q, %d);",
540                         BADGE_OPTION_TABLE_NAME,
541                          badge->pkgname, uid);
542         if (!sqlbuf) {
543                 /* LCOV_EXCL_START */
544                 ERR("fail to alloc query");
545                 result = BADGE_ERROR_OUT_OF_MEMORY;
546                 goto return_close_db;
547                 /* LCOV_EXCL_STOP */
548         }
549
550         ret = badge_db_exec(db, sqlbuf, NULL);
551         if (ret != BADGE_ERROR_NONE) {
552                 /* LCOV_EXCL_START */
553                 ERR("failed to insert badge option[%s], err[%d]",
554                                         badge->pkgname, sqlret);
555                 result = ret;
556                 goto return_close_db;
557                 /* LCOV_EXCL_STOP */
558         }
559
560 return_close_db:
561         if (sqlbuf)
562                 sqlite3_free(sqlbuf);
563
564         sqlret = db_util_close(db);
565         if (sqlret != SQLITE_OK)
566                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
567
568         return result;
569 }
570
571 int _badge_remove(const char *caller, const char *pkgname, uid_t uid, pid_t pid)
572 {
573         int ret = BADGE_ERROR_NONE;
574         int result = BADGE_ERROR_NONE;
575         sqlite3 *db = NULL;
576         int sqlret;
577         char *sqlbuf = NULL;
578
579         if (!caller || !pkgname)
580                 return BADGE_ERROR_INVALID_PARAMETER;
581
582         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
583         if (sqlret != SQLITE_OK || !db) {
584                 /* LCOV_EXCL_START */
585                 ERR("fail to db_util_open - [%d]", sqlret);
586                 return BADGE_ERROR_FROM_DB;
587                 /* LCOV_EXCL_STOP */
588         }
589
590         ret = _badge_check_data_inserted(pkgname, db, uid);
591         if (ret != BADGE_ERROR_ALREADY_EXIST) {
592                 result = ret;
593                 goto return_close_db;
594         }
595
596         ret = _badge_check_writable(caller, pkgname, db, uid, pid);
597         if (ret != BADGE_ERROR_NONE) {
598                 result = ret;
599                 goto return_close_db;
600         }
601
602         sqlbuf = sqlite3_mprintf("DELETE FROM %q WHERE pkgname = %Q AND uid = %d",
603                          BADGE_TABLE_NAME, pkgname, uid);
604         if (!sqlbuf) {
605                 /* LCOV_EXCL_START */
606                 ERR("fail to alloc query");
607                 result = BADGE_ERROR_OUT_OF_MEMORY;
608                 goto return_close_db;
609                 /* LCOV_EXCL_STOP */
610         }
611
612         ret = badge_db_exec(db, sqlbuf, NULL);
613         if (ret != BADGE_ERROR_NONE) {
614                 ERR("failed to remove badge[%s], err[%d]",
615                                 pkgname, ret);
616                 result = ret;
617                 goto return_close_db;
618         }
619
620         /* treating option table */
621         ret = _badge_check_option_inserted(pkgname, db, uid);
622         if (ret != BADGE_ERROR_ALREADY_EXIST) {
623                 result = ret;
624                 goto return_close_db;
625         }
626
627         sqlbuf = sqlite3_mprintf("DELETE FROM %q WHERE pkgname = %Q AND uid = %d",
628                         BADGE_OPTION_TABLE_NAME, pkgname, uid);
629         if (!sqlbuf) {
630                 /* LCOV_EXCL_START */
631                 ERR("fail to alloc query");
632                 result = BADGE_ERROR_OUT_OF_MEMORY;
633                 goto return_close_db;
634                 /* LCOV_EXCL_STOP */
635         }
636
637         ret = badge_db_exec(db, sqlbuf, NULL);
638         if (ret != BADGE_ERROR_NONE) {
639                 /* LCOV_EXCL_START */
640                 ERR("failed to remove badge option[%s], err[%d]",
641                                 pkgname, ret);
642                 result = ret;
643                 goto return_close_db;
644                 /* LCOV_EXCL_STOP */
645         }
646
647 return_close_db:
648         if (sqlbuf)
649                 sqlite3_free(sqlbuf);
650
651         sqlret = db_util_close(db);
652         if (sqlret != SQLITE_OK)
653                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
654
655         return result;
656 }
657
658 static int _badge_remove_by_appid(const char *appid, uid_t uid, sqlite3 *db)
659 {
660         int ret = BADGE_ERROR_NONE;
661         int result = BADGE_ERROR_NONE;
662         char *sqlbuf = NULL;
663
664         ret = _badge_check_data_inserted(appid, db, uid);
665         if (ret != BADGE_ERROR_ALREADY_EXIST) {
666                 result = ret;
667                 goto return_close_db;
668         }
669
670         sqlbuf = sqlite3_mprintf("DELETE FROM %q WHERE pkgname = %Q AND uid = %d",
671                          BADGE_TABLE_NAME, appid, uid);
672         if (!sqlbuf) {
673                 /* LCOV_EXCL_START */
674                 ERR("fail to alloc query");
675                 result = BADGE_ERROR_OUT_OF_MEMORY;
676                 goto return_close_db;
677                 /* LCOV_EXCL_STOP */
678         }
679
680         ret = badge_db_exec(db, sqlbuf, NULL);
681         if (ret != BADGE_ERROR_NONE) {
682                 ERR("failed to remove badge[%s], err[%d]",
683                                 appid, ret);
684                 result = ret;
685                 goto return_close_db;
686         }
687
688         /* treating option table */
689         ret = _badge_check_option_inserted(appid, db, uid);
690         if (ret != BADGE_ERROR_ALREADY_EXIST) {
691                 result = ret;
692                 goto return_close_db;
693         }
694
695         sqlbuf = sqlite3_mprintf("DELETE FROM %q WHERE pkgname = %Q AND uid = %d",
696                         BADGE_OPTION_TABLE_NAME, appid, uid);
697         if (!sqlbuf) {
698                 /* LCOV_EXCL_START */
699                 ERR("fail to alloc query");
700                 result = BADGE_ERROR_OUT_OF_MEMORY;
701                 goto return_close_db;
702                 /* LCOV_EXCL_STOP */
703         }
704
705         ret = badge_db_exec(db, sqlbuf, NULL);
706         if (ret != BADGE_ERROR_NONE) {
707                 /* LCOV_EXCL_START */
708                 ERR("failed to remove badge option[%s], err[%d]",
709                                 appid, ret);
710                 result = ret;
711                 goto return_close_db;
712                 /* LCOV_EXCL_STOP */
713         }
714
715 return_close_db:
716         if (sqlbuf)
717                 sqlite3_free(sqlbuf);
718
719         return result;
720 }
721
722 static bool _get_table_field_data_string(char **table, char **buf, int ucs2, int index)
723 {
724         bool ret = false;
725         int sLen = 0;
726         char *pTemp;
727
728         if (table == NULL || buf == NULL || index < 0) {
729                 /* LCOV_EXCL_START */
730                 ERR("table[%p], buf[%p], index[%d]", table, buf, index);
731                 return false;
732                 /* LCOV_EXCL_STOP */
733         }
734
735         pTemp = table[index];
736         if (pTemp == NULL) {
737                 *buf = NULL; /* LCOV_EXCL_LINE */
738         } else {
739                 sLen = strlen(pTemp);
740                 if (sLen) {
741                         *buf = (char *)malloc(sLen + 1);
742                         if (*buf == NULL) {
743                                 ERR("malloc is failed"); /* LCOV_EXCL_LINE */
744                                 goto out;
745                         }
746                         memset(*buf, 0, sLen + 1);
747                         strncpy(*buf, pTemp, sLen);
748                 } else {
749                         *buf = NULL; /* LCOV_EXCL_LINE */
750                 }
751         }
752
753         ret = true;
754
755 out:
756         return ret;
757 }
758
759 int _badge_remove_by_pkgname(const char *pkgname, uid_t uid)
760 {
761         int ret = BADGE_ERROR_NONE;
762         int sql_ret;
763         int row_count = 0;
764         int col_count = 0;
765         int col_index = 0;
766         int index;
767         char *sql_query = NULL;
768         char **query_result = NULL;
769         char *appid = NULL;
770         sqlite3 *db = NULL;
771
772         sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
773         if (sql_ret != SQLITE_OK || db == NULL) {
774                 ERR("Failed db util open [%s][%d]", BADGE_DB_PATH, sql_ret);
775                 return BADGE_ERROR_FROM_DB;
776         }
777
778         sql_query = sqlite3_mprintf("SELECT appid FROM %s WHERE pkgname = %Q" \
779                                 "AND (uid = %d OR uid = %d) ORDER BY uid DESC;",
780                                 BADGE_SETTING_DB_TABLE, pkgname, uid,
781                                 tzplatform_getuid(TZ_SYS_GLOBALAPP_USER));
782         if (!sql_query) {
783                 ERR("fail to alloc query");
784                 ret = BADGE_ERROR_FROM_DB;
785                 goto out;
786         }
787
788         sql_ret = sqlite3_get_table(db, sql_query, &query_result, &row_count, &col_count, NULL);
789         if (sql_ret != SQLITE_OK && sql_ret != -1) {
790                 ERR("sqlite3_get_table failed [%d][%s]", sql_ret, sql_query);
791                 ret = BADGE_ERROR_FROM_DB;
792                 goto out;
793         }
794
795         if (!row_count) {
796                 DBG("No setting found for [%s]", pkgname);
797                 ret = BADGE_ERROR_NOT_EXIST;
798                 goto out;
799         }
800
801         col_index = col_count;
802
803         for (index = 0; index < row_count; index++) {
804                 _get_table_field_data_string(query_result, &appid, 1, col_index++);
805                 if (appid) {
806                         _badge_remove_by_appid(appid, uid, db);
807                         free(appid);
808                         appid = NULL;
809                 }
810         }
811
812 out:
813         if (query_result)
814                 sqlite3_free_table(query_result);
815         if (sql_query)
816                 sqlite3_free(sql_query);
817         if (db) {
818                 sql_ret = db_util_close(db);
819                 if (sql_ret != SQLITE_OK)
820                         WARN("fail to db_util_close");
821         }
822
823         return ret;
824 }
825
826 int _badge_set_count(const char *caller, const char *pkgname,
827                         unsigned int count, uid_t uid, pid_t pid)
828 {
829         int ret = BADGE_ERROR_NONE;
830         int result = BADGE_ERROR_NONE;
831         sqlite3 *db = NULL;
832         char *sqlbuf = NULL;
833         int sqlret;
834
835         if (!caller || !pkgname)
836                 return BADGE_ERROR_INVALID_PARAMETER;
837
838         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
839         if (sqlret != SQLITE_OK || !db) {
840                 /* LCOV_EXCL_START */
841                 ERR("fail to db_util_open - [%d]", sqlret);
842                 return BADGE_ERROR_FROM_DB;
843                 /* LCOV_EXCL_STOP */
844         }
845
846         ret = _badge_check_data_inserted(pkgname, db, uid);
847         if (ret != BADGE_ERROR_ALREADY_EXIST) {
848                 result = ret;
849                 goto return_close_db;
850         }
851
852         ret = _badge_check_writable(caller, pkgname, db, uid, pid);
853         if (ret != BADGE_ERROR_NONE) {
854                 result = ret;
855                 goto return_close_db;
856         }
857
858         sqlbuf = sqlite3_mprintf("UPDATE %q SET badge = %d " \
859                         "WHERE pkgname = %Q AND uid = %d",
860                          BADGE_TABLE_NAME, count, pkgname, uid);
861         if (!sqlbuf) {
862                 /* LCOV_EXCL_START */
863                 ERR("fail to alloc query");
864                 result = BADGE_ERROR_OUT_OF_MEMORY;
865                 goto return_close_db;
866                 /* LCOV_EXCL_STOP */
867         }
868
869         ret = badge_db_exec(db, sqlbuf, NULL);
870         if (ret != BADGE_ERROR_NONE) {
871                 /* LCOV_EXCL_START */
872                 ERR("failed to set badge[%s] count[%d], err[%d]",
873                                 pkgname, count, ret);
874                 result = ret;
875                 goto return_close_db;
876                 /* LCOV_EXCL_STOP */
877         }
878
879 return_close_db:
880         if (sqlbuf)
881                 sqlite3_free(sqlbuf);
882
883         sqlret = db_util_close(db);
884         if (sqlret != SQLITE_OK)
885                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
886
887         return result;
888 }
889
890 int _badge_get_count(const char *pkgname, unsigned int *count, uid_t uid)
891 {
892         int ret = BADGE_ERROR_NONE;
893         int result = BADGE_ERROR_NONE;
894         sqlite3 *db = NULL;
895         char *sqlbuf = NULL;
896         sqlite3_stmt *stmt = NULL;
897         int sqlret;
898
899         if (!pkgname || !count)
900                 return BADGE_ERROR_INVALID_PARAMETER;
901
902         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
903         if (sqlret != SQLITE_OK || !db) {
904                 /* LCOV_EXCL_START */
905                 ERR("fail to db_util_open - [%d]", sqlret);
906                 if (sqlret == SQLITE_PERM)
907                         return BADGE_ERROR_PERMISSION_DENIED;
908                 else
909                         return BADGE_ERROR_FROM_DB;
910                 /* LCOV_EXCL_STOP */
911         }
912
913         ret = _badge_check_data_inserted(pkgname, db, uid);
914         if (ret != BADGE_ERROR_ALREADY_EXIST) {
915                 result = ret;
916                 goto return_close_db;
917         }
918
919         sqlbuf = sqlite3_mprintf("SELECT badge FROM %q " \
920                         "WHERE pkgname = %Q AND uid = %d",
921                          BADGE_TABLE_NAME, pkgname, uid);
922         if (!sqlbuf) {
923                 /* LCOV_EXCL_START */
924                 ERR("fail to alloc query");
925                 result = BADGE_ERROR_OUT_OF_MEMORY;
926                 goto return_close_db;
927                 /* LCOV_EXCL_STOP */
928         }
929
930         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
931         if (sqlret != SQLITE_OK) {
932                 /* LCOV_EXCL_START */
933                 ERR("fail to prepare %s - [%s]",
934                                 sqlbuf, sqlite3_errmsg(db));
935                 result = BADGE_ERROR_FROM_DB;
936                 goto return_close_db;
937                 /* LCOV_EXCL_STOP */
938         }
939
940         sqlret = sqlite3_step(stmt);
941         if (sqlret == SQLITE_ROW)
942                 *count = (unsigned int)sqlite3_column_int(stmt, 0);
943         else
944                 *count = (unsigned int)0;
945
946 return_close_db:
947         if (sqlbuf)
948                 sqlite3_free(sqlbuf);
949
950         if (stmt)
951                 sqlite3_finalize(stmt);
952
953         sqlret = db_util_close(db);
954         if (sqlret != SQLITE_OK)
955                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
956
957         return result;
958 }
959
960 int _badge_set_display(const char *pkgname, unsigned int is_display, uid_t uid)
961 {
962         int ret = BADGE_ERROR_NONE;
963         int result = BADGE_ERROR_NONE;
964         sqlite3 *db = NULL;
965         char *sqlbuf = NULL;
966         int sqlret;
967
968         if (!pkgname)
969                 return BADGE_ERROR_INVALID_PARAMETER;
970
971         if (is_display != 0 && is_display != 1)
972                 return BADGE_ERROR_INVALID_PARAMETER;
973
974         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
975         if (sqlret != SQLITE_OK || !db) {
976                 /* LCOV_EXCL_START */
977                 ERR("fail to db_util_open - [%d]", sqlret);
978                 return BADGE_ERROR_FROM_DB;
979                 /* LCOV_EXCL_STOP */
980         }
981
982         ret = _badge_check_data_inserted(pkgname, db, uid);
983         if (ret != BADGE_ERROR_ALREADY_EXIST) {
984                 result = ret;
985                 goto return_close_db;
986         }
987
988         ret = _badge_check_option_inserted(pkgname, db, uid);
989         if (ret == BADGE_ERROR_ALREADY_EXIST) {
990                 sqlbuf = sqlite3_mprintf("UPDATE %q SET display = %d " \
991                                 "WHERE pkgname = %Q AND uid = %d",
992                                 BADGE_OPTION_TABLE_NAME, is_display, pkgname, uid);
993                 if (!sqlbuf) {
994                         /* LCOV_EXCL_START */
995                         ERR("fail to alloc query");
996                         result = BADGE_ERROR_OUT_OF_MEMORY;
997                         goto return_close_db;
998                         /* LCOV_EXCL_STOP */
999                 }
1000
1001                 ret = badge_db_exec(db, sqlbuf, NULL);
1002                 if (ret != BADGE_ERROR_NONE) {
1003                         /* LCOV_EXCL_START */
1004                         ERR("failed to set badge[%s] option[%d], err[%d]",
1005                                         pkgname, is_display, ret);
1006                         result = ret;
1007                         goto return_close_db;
1008                         /* LCOV_EXCL_STOP */
1009                 }
1010
1011         } else if (ret == BADGE_ERROR_NOT_EXIST) {
1012                 sqlbuf = sqlite3_mprintf("INSERT INTO %q " \
1013                                 "(pkgname, " \
1014                                 "display, " \
1015                                 "uid) " \
1016                                 "VALUES "
1017                                 "(%Q, %d, %d);",
1018                                 BADGE_OPTION_TABLE_NAME,
1019                                 pkgname, is_display, uid);
1020                 if (!sqlbuf) {
1021                         /* LCOV_EXCL_START */
1022                         ERR("fail to alloc query");
1023                         result = BADGE_ERROR_OUT_OF_MEMORY;
1024                         goto return_close_db;
1025                         /* LCOV_EXCL_STOP */
1026                 }
1027
1028                 ret = badge_db_exec(db, sqlbuf, NULL);
1029                 if (ret != BADGE_ERROR_NONE) {
1030                         /* LCOV_EXCL_START */
1031                         ERR("failed to set badge[%s] option[%d], err[%d]",
1032                                         pkgname, is_display, ret);
1033                         result = ret;
1034                         goto return_close_db;
1035                         /* LCOV_EXCL_STOP */
1036                 }
1037         } else {
1038                 result = ret;
1039                 goto return_close_db;
1040         }
1041
1042 return_close_db:
1043         if (sqlbuf)
1044                 sqlite3_free(sqlbuf);
1045
1046         sqlret = db_util_close(db);
1047         if (sqlret != SQLITE_OK)
1048                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
1049
1050         return result;
1051 }
1052
1053 int _badge_get_display(const char *pkgname, unsigned int *is_display, uid_t uid)
1054 {
1055         int ret = BADGE_ERROR_NONE;
1056         int result = BADGE_ERROR_NONE;
1057         sqlite3 *db = NULL;
1058         char *sqlbuf = NULL;
1059         sqlite3_stmt *stmt = NULL;
1060         int sqlret;
1061
1062         if (!pkgname || !is_display)
1063                 return BADGE_ERROR_INVALID_PARAMETER;
1064
1065         sqlret = db_util_open(BADGE_DB_PATH, &db, 0);
1066         if (sqlret != SQLITE_OK || !db) {
1067                 /* LCOV_EXCL_START */
1068                 ERR("fail to db_util_open - [%d]", sqlret);
1069                 if (sqlret == SQLITE_PERM)
1070                         return BADGE_ERROR_PERMISSION_DENIED;
1071                 else
1072                         return BADGE_ERROR_FROM_DB;
1073                 /* LCOV_EXCL_STOP */
1074         }
1075
1076         ret = _badge_check_option_inserted(pkgname, db, uid);
1077         if (ret != BADGE_ERROR_ALREADY_EXIST) {
1078                 if (ret == BADGE_ERROR_NOT_EXIST)
1079                         *is_display = 1;
1080
1081                 result = ret;
1082                 goto return_close_db;
1083         }
1084
1085         sqlbuf = sqlite3_mprintf("SELECT display FROM %q " \
1086                         "WHERE pkgname = %Q AND uid = %d",
1087                         BADGE_OPTION_TABLE_NAME, pkgname, uid);
1088         if (!sqlbuf) {
1089                 /* LCOV_EXCL_START */
1090                 ERR("fail to alloc query");
1091                 result = BADGE_ERROR_OUT_OF_MEMORY;
1092                 goto return_close_db;
1093                 /* LCOV_EXCL_STOP */
1094         }
1095
1096         sqlret = sqlite3_prepare_v2(db, sqlbuf, -1, &stmt, NULL);
1097         if (sqlret != SQLITE_OK) {
1098                 /* LCOV_EXCL_START */
1099                 ERR("fail to prepare %s - [%s]",
1100                                 sqlbuf, sqlite3_errmsg(db));
1101                 result = BADGE_ERROR_FROM_DB;
1102                 goto return_close_db;
1103                 /* LCOV_EXCL_STOP */
1104         }
1105
1106         sqlret = sqlite3_step(stmt);
1107         if (sqlret == SQLITE_ROW)
1108                 *is_display = (unsigned int)sqlite3_column_int(stmt, 0);
1109         else
1110                 *is_display = (unsigned int)1;
1111
1112 return_close_db:
1113         if (sqlbuf)
1114                 sqlite3_free(sqlbuf);
1115
1116         if (stmt)
1117                 sqlite3_finalize(stmt);
1118
1119         sqlret = db_util_close(db);
1120         if (sqlret != SQLITE_OK)
1121                 WARN("fail to db_util_close - [%d]", sqlret); /* LCOV_EXCL_LINE */
1122
1123         return result;
1124 }
1125
1126 void badge_changed_cb_call(unsigned int action, const char *pkgname,
1127                         unsigned int count, uid_t uid)
1128 {
1129         GList *badge_cb_list = NULL;
1130         struct _badge_cb_data *bd = NULL;
1131
1132         DBG("call badge_change_cb");
1133
1134         if (_badge_cb_hash == NULL)
1135                 return;
1136
1137         badge_cb_list = (GList *)g_hash_table_lookup(_badge_cb_hash, GUINT_TO_POINTER(uid));
1138
1139         if (badge_cb_list == NULL) {
1140                 ERR("invalid data");
1141                 return;
1142         }
1143
1144         badge_cb_list = g_list_first(badge_cb_list);
1145
1146         for (; badge_cb_list != NULL; badge_cb_list = badge_cb_list->next) {
1147                 bd = badge_cb_list->data;
1148
1149                 if (bd != NULL && bd->callback != NULL) {
1150                         DBG("call badge_change_cb : action %d, pkgname %s, count %d",
1151                             action, pkgname, count);
1152                         bd->callback(action, pkgname, count, bd->data);
1153                 }
1154         }
1155 }
1156
1157 static int _badge_changed_monitor_init(uid_t uid)
1158 {
1159         return badge_ipc_monitor_init(uid);
1160 }
1161
1162 static void _badge_chanaged_monitor_fini()
1163 {
1164         badge_ipc_monitor_fini();
1165 }
1166
1167 static gint _badge_data_compare(gconstpointer a, gconstpointer b)
1168 {
1169         const struct _badge_cb_data *bd = NULL;
1170
1171         if (!a)
1172                 return -1;
1173         bd = (struct _badge_cb_data *)a;
1174
1175         if (bd->callback == b)
1176                 return 0;
1177
1178         return 1;
1179 }
1180
1181 static struct _badge_cb_data *__malloc_badge_cb_data(badge_change_cb callback, void *data)
1182 {
1183         struct _badge_cb_data *bd = NULL;
1184         bd = (struct _badge_cb_data *)malloc(sizeof(struct _badge_cb_data));
1185         if (bd == NULL) {
1186                 ERR("failed malloc badge_cb_data");
1187                 return NULL;
1188         }
1189
1190         bd->callback = callback;
1191         bd->data = data;
1192
1193         return bd;
1194 }
1195
1196 int _badge_free(badge_h *badge)
1197 {
1198         if (!badge)
1199                 return BADGE_ERROR_INVALID_PARAMETER;
1200
1201         if (badge->pkgname)
1202                 free(badge->pkgname);
1203
1204         if (badge->writable_pkgs)
1205                 free(badge->writable_pkgs);
1206
1207         free(badge);
1208
1209         return BADGE_ERROR_NONE;
1210 }
1211
1212 badge_h *_badge_new(const char *pkgname, const char *writable_pkgs,
1213                 int *err)
1214 {
1215         badge_h *badge = NULL;
1216
1217         if (!pkgname || !writable_pkgs) {
1218                 ERR("Invalid parameters");
1219                 if (err)
1220                         *err = BADGE_ERROR_INVALID_PARAMETER;
1221                 return NULL;
1222         }
1223
1224         badge = (badge_h *)malloc(sizeof(struct _badge_h));
1225         if (!badge) {
1226                 ERR("fail to alloc handle");
1227                 if (err)
1228                         *err = BADGE_ERROR_OUT_OF_MEMORY;
1229                 return NULL;
1230         }
1231
1232         badge->pkgname = strdup(pkgname);
1233         badge->writable_pkgs = strdup(writable_pkgs);
1234         if (err)
1235                 *err = BADGE_ERROR_NONE;
1236
1237         return badge;
1238 }
1239
1240 char *_badge_pkgs_new(int *err, const char *pkg1, ...)
1241 {
1242         char *caller_pkgname = NULL;
1243         char *s = NULL;
1244         char *result = NULL;
1245         char *ptr = NULL;
1246         gsize length;
1247         va_list args;
1248         char *new_pkgs = NULL;
1249
1250         if (err)
1251                 *err = BADGE_ERROR_NONE;
1252
1253         caller_pkgname = _badge_get_pkgname_by_pid();
1254         if (!caller_pkgname) {
1255                 ERR("fail to get caller pkgname");
1256                 if (err)
1257                         *err = BADGE_ERROR_PERMISSION_DENIED;
1258                 return NULL;
1259         }
1260
1261         if (!pkg1) {
1262                 WARN("pkg1 is NULL");
1263                 return caller_pkgname;
1264         }
1265
1266         length = strlen(pkg1);
1267         va_start(args, pkg1);
1268         s = va_arg(args, char *);
1269         while (s) {
1270                 length += strlen(s) ;
1271                 s = va_arg(args, char *);
1272         }
1273         va_end(args);
1274
1275         if (length <= 0) {
1276                 WARN("length is %d", length);
1277                 return caller_pkgname;
1278         }
1279
1280         result = g_new0(char, length + 1); /* 1 for null terminate */
1281         if (!result) {
1282                 /* LCOV_EXCL_START */
1283                 ERR("fail to alloc memory");
1284                 if (err)
1285                         *err = BADGE_ERROR_OUT_OF_MEMORY;
1286                 free(caller_pkgname);
1287                 return NULL;
1288                 /* LCOV_EXCL_STOP */
1289         }
1290
1291         ptr = result;
1292         ptr = g_stpcpy(ptr, pkg1);
1293         va_start(args, pkg1);
1294         s = va_arg(args, char *);
1295         while (s) {
1296                 ptr = g_stpcpy(ptr, s);
1297                 s = va_arg(args, char *);
1298         }
1299         va_end(args);
1300
1301         if (g_strstr_len(result, -1, caller_pkgname) == NULL) {
1302                 new_pkgs = g_strdup_printf("%s%s", caller_pkgname, result);
1303                 if (!new_pkgs) {
1304                         ERR("fail to alloc memory");
1305                         if (err)
1306                                 *err = BADGE_ERROR_OUT_OF_MEMORY;
1307
1308                         free(result);
1309                         free(caller_pkgname);
1310                         return NULL;
1311                 }
1312                 free(result);
1313                 result = new_pkgs;
1314         }
1315
1316         free(caller_pkgname);
1317
1318         return result;
1319 }
1320
1321 EXPORT_API
1322 int badge_create_for_uid(const char *pkgname, const char *writable_pkg, uid_t uid)
1323 {
1324         char *caller = NULL;
1325         int err = BADGE_ERROR_NONE;
1326
1327         caller = _badge_get_pkgname_by_pid();
1328         if (!caller) {
1329                 ERR("fail to get caller pkgname");
1330                 return BADGE_ERROR_PERMISSION_DENIED;
1331         }
1332
1333         err = badge_ipc_request_insert(pkgname, writable_pkg, caller, uid);
1334
1335         free(caller);
1336         return err;
1337 }
1338
1339 EXPORT_API
1340 int badge_new_for_uid(const char *writable_app_id, uid_t uid)
1341 {
1342         char *caller = NULL;
1343         int err = BADGE_ERROR_NONE;
1344
1345         caller = _badge_get_pkgname_by_pid();
1346         if (!caller) {
1347                 ERR("fail to get caller pkgname");
1348                 return BADGE_ERROR_PERMISSION_DENIED;
1349         }
1350
1351         err = badge_ipc_request_insert(caller, writable_app_id, caller, uid);
1352
1353         free(caller);
1354         return err;
1355 }
1356
1357 EXPORT_API
1358 int badge_add_for_uid(const char *badge_app_id, uid_t uid)
1359 {
1360         char *caller = NULL;
1361         int err = BADGE_ERROR_NONE;
1362
1363         caller = _badge_get_pkgname_by_pid();
1364         if (!caller) {
1365                 ERR("fail to get caller pkgname");
1366                 return BADGE_ERROR_PERMISSION_DENIED;
1367         }
1368
1369         if (badge_app_id == NULL) {
1370                 badge_app_id = caller;
1371         } else {
1372                 int pkgmgr_ret  = PACKAGE_MANAGER_ERROR_NONE;
1373                 package_manager_compare_result_type_e compare_result = PACKAGE_MANAGER_COMPARE_MISMATCH;
1374
1375                 pkgmgr_ret = package_manager_compare_app_cert_info(badge_app_id, caller, &compare_result);
1376
1377                 if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE || compare_result != PACKAGE_MANAGER_COMPARE_MATCH) {
1378                         err = BADGE_ERROR_INVALID_PACKAGE;
1379                         goto out;
1380                 }
1381         }
1382
1383         err = badge_ipc_request_insert(badge_app_id, caller, caller, uid);
1384
1385 out:
1386         if (caller)
1387                 free(caller);
1388         return err;
1389 }
1390
1391 EXPORT_API
1392 int badge_remove_for_uid(const char *app_id, uid_t uid)
1393 {
1394         char *caller = NULL;
1395         int result = BADGE_ERROR_NONE;
1396
1397         caller = _badge_get_pkgname_by_pid();
1398         if (!caller) {
1399                 ERR("fail to get caller pkgname");
1400                 result = BADGE_ERROR_PERMISSION_DENIED;
1401                 goto out;
1402         }
1403
1404         result = badge_ipc_request_delete(app_id, caller, uid);
1405
1406 out:
1407         if (caller)
1408                 free(caller);
1409         return result;
1410 }
1411
1412 EXPORT_API
1413 int badge_is_existing_for_uid(const char *app_id, bool *existing, uid_t uid)
1414 {
1415         return badge_ipc_request_is_existing(app_id, existing, uid);
1416 }
1417
1418 EXPORT_API
1419 int badge_foreach_for_uid(badge_foreach_cb callback, void *user_data, uid_t uid)
1420 {
1421         int result = BADGE_ERROR_NONE;
1422         result = badge_ipc_request_get_list(callback, user_data, uid);
1423         if (result == BADGE_ERROR_IO_ERROR)
1424                 result = BADGE_ERROR_FROM_DB;
1425         return result;
1426 }
1427
1428 EXPORT_API
1429 int badge_set_count_for_uid(const char *app_id, unsigned int count, uid_t uid)
1430 {
1431         char *caller = NULL;
1432         int result = BADGE_ERROR_NONE;
1433
1434         DBG("app_id %s, count %d", app_id, count);
1435
1436         caller = _badge_get_pkgname_by_pid();
1437         if (!caller) {
1438                 ERR("fail to get caller pkgname");
1439                 result = BADGE_ERROR_PERMISSION_DENIED;
1440                 goto out;
1441         }
1442
1443         result = badge_ipc_request_set_count(app_id, caller, count, uid);
1444 out:
1445         if (caller)
1446                 free(caller);
1447         return result;
1448 }
1449
1450 EXPORT_API
1451 int badge_get_count_for_uid(const char *app_id, unsigned int *count, uid_t uid)
1452 {
1453         int result = BADGE_ERROR_NONE;
1454
1455         result = badge_ipc_request_get_count(app_id, count, uid);
1456         if (result == BADGE_ERROR_IO_ERROR)
1457                 result = BADGE_ERROR_FROM_DB;
1458
1459         return result;
1460 }
1461
1462 EXPORT_API
1463 int badge_set_display_for_uid(const char *app_id, unsigned int is_display, uid_t uid)
1464 {
1465         char *caller = NULL;
1466         int result = BADGE_ERROR_NONE;
1467
1468         caller = _badge_get_pkgname_by_pid();
1469         if (!caller) {
1470                 ERR("fail to get caller pkgname");
1471                 result = BADGE_ERROR_PERMISSION_DENIED;
1472                 goto out;
1473         }
1474
1475         result = badge_ipc_request_set_display(app_id, caller, is_display, uid);
1476
1477 out:
1478         if (caller)
1479                 free(caller);
1480         return result;
1481 }
1482
1483 EXPORT_API
1484 int badge_get_display_for_uid(const char *app_id, unsigned int *is_display, uid_t uid)
1485 {
1486         int result = BADGE_ERROR_NONE;
1487
1488         result = badge_ipc_request_get_display(app_id, is_display, uid);
1489         if (result == BADGE_ERROR_IO_ERROR)
1490                 result = BADGE_ERROR_FROM_DB;
1491
1492         return result;
1493 }
1494
1495 EXPORT_API
1496 int badge_register_changed_cb_for_uid(badge_change_cb callback, void *data, uid_t uid)
1497 {
1498         struct _badge_cb_data *bd = NULL;
1499         GList *badge_cb_list = NULL;
1500         GList *badge_found_list = NULL;
1501         int ret;
1502
1503         if (_badge_cb_hash == NULL)
1504                 _badge_cb_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
1505
1506         badge_cb_list = (GList *)g_hash_table_lookup(_badge_cb_hash, GUINT_TO_POINTER(uid));
1507
1508         if (badge_cb_list == NULL) {
1509                 bd = __malloc_badge_cb_data(callback, data);
1510                 if (!bd)
1511                         return BADGE_ERROR_OUT_OF_MEMORY;
1512
1513                 badge_cb_list = g_list_append(badge_cb_list, bd);
1514                 g_hash_table_insert(_badge_cb_hash, GUINT_TO_POINTER(uid), badge_cb_list);
1515         } else {
1516                 badge_found_list = g_list_find_custom(g_list_first(badge_cb_list), (gconstpointer)callback,
1517                                                       (GCompareFunc)_badge_data_compare);
1518                 if (badge_found_list) {
1519                         bd = g_list_nth_data(badge_found_list, 0);
1520                         bd->data = data;
1521                 } else {
1522                         bd = __malloc_badge_cb_data(callback, data);
1523                         if (!bd)
1524                                 return BADGE_ERROR_OUT_OF_MEMORY;
1525                         badge_cb_list = g_list_append(badge_cb_list, bd);
1526                 }
1527         }
1528
1529         ret = _badge_changed_monitor_init(uid);
1530         if (ret == BADGE_ERROR_NONE) {
1531                 ret = badge_ipc_init_badge(uid);
1532                 if (ret != BADGE_ERROR_NONE && ret != BADGE_ERROR_NOT_EXIST)
1533                         return ret;
1534         } else {
1535                 /* LCOV_EXCL_START */
1536                 ERR("badge_ipc_monitor_init err : %d", ret);
1537                 badge_unregister_changed_cb_for_uid(callback, uid);
1538                 return ret;
1539                 /* LCOV_EXCL_STOP */
1540         }
1541         return BADGE_ERROR_NONE;
1542 }
1543
1544 EXPORT_API
1545 int badge_unregister_changed_cb_for_uid(badge_change_cb callback, uid_t uid)
1546 {
1547         GList *badge_cb_list = NULL;
1548         GList *badge_delete_list = NULL;
1549         struct _badge_cb_data *bd = NULL;
1550
1551         if (_badge_cb_hash == NULL)
1552                 return BADGE_ERROR_INVALID_PARAMETER;
1553
1554         badge_cb_list = (GList *)g_hash_table_lookup(_badge_cb_hash, GUINT_TO_POINTER(uid));
1555
1556         if (badge_cb_list == NULL)
1557                 return BADGE_ERROR_INVALID_PARAMETER;
1558
1559         badge_delete_list = g_list_find_custom(g_list_first(badge_cb_list), (gconstpointer)callback,
1560                                                (GCompareFunc)_badge_data_compare);
1561
1562         if (badge_delete_list) {
1563                 bd = g_list_nth_data(badge_delete_list, 0);
1564                 badge_cb_list = g_list_delete_link(badge_cb_list, badge_delete_list);
1565                 free(bd);
1566         } else {
1567                 return BADGE_ERROR_INVALID_PARAMETER;
1568         }
1569
1570         if (badge_cb_list == NULL)
1571                 g_hash_table_steal(_badge_cb_hash, GUINT_TO_POINTER(uid));
1572         else
1573                 g_hash_table_replace(_badge_cb_hash, GUINT_TO_POINTER(uid), badge_cb_list);
1574
1575         if (g_hash_table_size(_badge_cb_hash) == 0)
1576                 _badge_chanaged_monitor_fini();
1577
1578         return BADGE_ERROR_NONE;
1579 }
1580
1581 EXPORT_API
1582 int badge_is_service_ready(void)
1583 {
1584         return badge_ipc_is_master_ready();
1585 }
1586
1587 EXPORT_API
1588 int badge_add_deferred_task(
1589                 void (*badge_add_deferred_task)(void *data), void *user_data)
1590 {
1591         return badge_ipc_add_deferred_task(badge_add_deferred_task, user_data);
1592 }
1593
1594 EXPORT_API
1595 int badge_del_deferred_task(
1596                 void (*badge_add_deferred_task)(void *data))
1597 {
1598         return badge_ipc_del_deferred_task(badge_add_deferred_task);
1599 }
1600
1601 EXPORT_API
1602 int badge_is_existing(const char *app_id, bool *existing)
1603 {
1604         if (app_id == NULL || existing == NULL)
1605                 return BADGE_ERROR_INVALID_PARAMETER;
1606
1607         return badge_is_existing_for_uid(app_id, existing, getuid());
1608 }
1609
1610 EXPORT_API
1611 int badge_create(const char *pkgname, const char *writable_pkg)
1612 {
1613         if (pkgname == NULL)
1614                 return BADGE_ERROR_INVALID_PARAMETER;
1615
1616         return badge_create_for_uid(pkgname, writable_pkg, getuid());
1617 }