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