706cc057861ab0682f5cbacdf05b4a5917fd3d41
[platform/core/appfw/badge.git] / src / badge_setting_service.c
1 /*
2  * Copyright (c) 2016 - 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 <sqlite3.h>
19 #include <db-util.h>
20 #include <gio/gio.h>
21 #include <string.h>
22 #include <pkgmgr-info.h>
23 #include <package_manager.h>
24
25 #include "badge_setting.h"
26 #include "badge_setting_service.h"
27 #include "badge_db.h"
28 #include "badge_error.h"
29 #include "badge_log.h"
30
31 #define BADGE_PRIVILEGE "http://tizen.org/privilege/notification"
32
33 typedef struct {
34         uid_t uid;
35         sqlite3 *db;
36 } badge_setting_info;
37
38 static bool _get_table_field_data_int(char **table, int *buf, int index)
39 {
40         if (table == NULL || buf == NULL || index < 0) {
41                 /* LCOV_EXCL_START */
42                 ERR("table[%p], buf[%p], index[%d]", table, buf, index);
43                 return false;
44                 /* LCOV_EXCL_STOP */
45         }
46
47         if (table[index] != NULL) {
48                 *buf = atoi(table[index]);
49                 return true;
50         }
51
52         /* LCOV_EXCL_START */
53         *buf = 0;
54         return false;
55         /* LCOV_EXCL_STOP */
56 }
57
58 static bool _get_table_field_data_string(char **table, char **buf, int ucs2, int index)
59 {
60         bool ret = false;
61         int sLen = 0;
62         char *pTemp;
63
64         if (table == NULL || buf == NULL || index < 0) {
65                 /* LCOV_EXCL_START */
66                 ERR("table[%p], buf[%p], index[%d]", table, buf, index);
67                 return false;
68                 /* LCOV_EXCL_STOP */
69         }
70
71         pTemp = table[index];
72         if (pTemp == NULL) {
73                 *buf = NULL; /* LCOV_EXCL_LINE */
74         } else {
75                 sLen = strlen(pTemp);
76                 if (sLen) {
77                         *buf = (char *)malloc(sLen + 1);
78                         if (*buf == NULL) {
79                                 ERR("malloc is failed"); /* LCOV_EXCL_LINE */
80                                 goto out;
81                         }
82                         memset(*buf, 0, sLen + 1);
83                         strncpy(*buf, pTemp, sLen);
84                 } else {
85                         *buf = NULL; /* LCOV_EXCL_LINE */
86                 }
87         }
88
89         ret = true;
90
91 out:
92         return ret;
93 }
94
95 EXPORT_API int badge_db_get_setting_by_appid(const char *appid, badge_setting_h *setting, uid_t uid)
96 {
97         int ret = BADGE_ERROR_NONE;
98         int sql_ret;
99         int row_count;
100         int col_count;
101         int col_index;
102         char *sql_query = NULL;
103         char **query_result = NULL;
104         badge_setting_h result_setting;
105         sqlite3 *db = NULL;
106
107         if (appid == NULL)
108                 return BADGE_ERROR_INVALID_PARAMETER;
109
110         sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
111         if (sql_ret != SQLITE_OK || db == NULL) {
112                 ERR("Failed db util open [%s][%d]", BADGE_DB_PATH, sql_ret);
113                 return BADGE_ERROR_FROM_DB;
114         }
115
116         sql_query = sqlite3_mprintf("SELECT pkgname, appid, allow_to_display FROM %s " \
117                                 "WHERE appid = %Q AND (uid = %d OR uid = %d) " \
118                                 "ORDER BY uid DESC;",
119                                 BADGE_SETTING_DB_TABLE, appid, uid, tzplatform_getuid(TZ_SYS_GLOBALAPP_USER));
120         if (!sql_query) {
121                 ERR("Failed to alloc query");
122                 ret = BADGE_ERROR_FROM_DB;
123                 goto out;
124         }
125
126         sql_ret = sqlite3_get_table(db, sql_query, &query_result, &row_count, &col_count, NULL);
127         if (sql_ret != SQLITE_OK && sql_ret != -1) {
128                 ERR("sqlite3_get_table failed [%d][%s]", sql_ret,
129                                         sqlite3_errmsg(db));
130                 ret = BADGE_ERROR_FROM_DB;
131                 goto out;
132         }
133
134         if (!row_count) {
135                 DBG("No setting found for [%s]", appid);
136                 ret = BADGE_ERROR_NOT_EXIST;
137                 goto out;
138         }
139
140         result_setting = (struct badge_setting *)malloc(sizeof(struct badge_setting));
141         if (result_setting == NULL) {
142                 ERR("Failed to alloc setting");
143                 ret = BADGE_ERROR_OUT_OF_MEMORY;
144                 goto out;
145         }
146
147         col_index = col_count;
148
149         _get_table_field_data_string(query_result, &(result_setting[0].pkgname), 1, col_index++);
150         _get_table_field_data_string(query_result, &(result_setting[0].appid), 1, col_index++);
151         _get_table_field_data_int(query_result, (int *)&(result_setting[0].allow_to_display), col_index++);
152
153         *setting = result_setting;
154
155 out:
156         if (query_result)
157                 sqlite3_free_table(query_result);
158         if (sql_query)
159                 sqlite3_free(sql_query);
160         if (db) {
161                 sql_ret = db_util_close(db);
162                 if (sql_ret != SQLITE_OK)
163                         WARN("Failed to db_util_close");
164         }
165
166         return ret;
167 }
168
169 EXPORT_API int badge_db_update_setting(char *pkgname, char *appid, int allow_to_display, uid_t uid)
170 {
171         int ret = BADGE_ERROR_NONE;
172         sqlite3 *db = NULL;
173         char *sqlbuf = NULL;
174         int sql_ret;
175
176         if (pkgname == NULL || appid == NULL) {
177                 ERR("Invalid package name or app id");
178                 return BADGE_ERROR_INVALID_PARAMETER;
179         }
180
181         sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
182         if (sql_ret != SQLITE_OK || db == NULL) {
183                 ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sql_ret);
184                 return BADGE_ERROR_FROM_DB;
185         }
186
187         sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_display = %d " \
188                                 "WHERE pkgname = %Q AND appid = %Q " \
189                                 "AND uid = %d;",
190                                 BADGE_SETTING_DB_TABLE, allow_to_display,
191                                 pkgname, appid, uid);
192
193         if (!sqlbuf) {
194                 ERR("Failed to alloc query");
195                 ret = BADGE_ERROR_FROM_DB;
196                 goto out;
197         }
198
199         ret = badge_db_exec(db, sqlbuf, NULL);
200
201 out:
202         if (sqlbuf)
203                 sqlite3_free(sqlbuf);
204         if (db) {
205                 sql_ret = db_util_close(db);
206                 if (sql_ret != SQLITE_OK)
207                         WARN("Failed to db_util_close");
208         }
209
210         return ret;
211 }
212
213 EXPORT_API int badge_db_get_allow_to_display_by_appid(char *appid, int *allow_to_display, uid_t uid)
214 {
215         int ret = BADGE_ERROR_NONE;
216         int sql_ret;
217         int row_count;
218         int col_count;
219         int col_index;
220         char *sql_query = NULL;
221         char **query_result = NULL;
222         sqlite3 *db = NULL;
223
224         if (appid == NULL)
225                 return BADGE_ERROR_INVALID_PARAMETER;
226
227         sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
228         if (sql_ret != SQLITE_OK || db == NULL) {
229                 ERR("Failed db util open [%s][%d]", BADGE_DB_PATH, sql_ret);
230                 return BADGE_ERROR_FROM_DB;
231         }
232
233         sql_query = sqlite3_mprintf("SELECT allow_to_display FROM %s WHERE appid = %Q " \
234                                 "AND (uid = %d OR uid = %d) ORDER BY uid DESC;",
235                                 BADGE_SETTING_DB_TABLE, appid, uid,
236                                 tzplatform_getuid(TZ_SYS_GLOBALAPP_USER));
237         if (!sql_query) {
238                 ERR("Failed to alloc query");
239                 ret = BADGE_ERROR_FROM_DB;
240                 goto out;
241         }
242
243         sql_ret = sqlite3_get_table(db, sql_query, &query_result, &row_count, &col_count, NULL);
244         if (sql_ret != SQLITE_OK && sql_ret != -1) {
245                 ERR("sqlite3_get_table failed [%d][%s]", sql_ret,
246                                         sqlite3_errmsg(db));
247                 ret = BADGE_ERROR_FROM_DB;
248                 goto out;
249         }
250
251         if (!row_count) {
252                 DBG("No setting found for [%s]", appid);
253                 ret = BADGE_ERROR_NOT_EXIST;
254                 goto out;
255         }
256
257         col_index = col_count;
258
259         _get_table_field_data_int(query_result, (int *)allow_to_display, col_index++);
260
261 out:
262         if (query_result)
263                 sqlite3_free_table(query_result);
264         if (sql_query)
265                 sqlite3_free(sql_query);
266         if (db) {
267                 sql_ret = db_util_close(db);
268                 if (sql_ret != SQLITE_OK)
269                         WARN("Failed to db_util_close");
270         }
271
272         return ret;
273 }
274
275 static bool _is_package_in_setting_table(sqlite3 *db, const char *pkgname, const char* appid, uid_t uid)
276 {
277         sqlite3_stmt *db_statement = NULL;
278         int sqlite3_ret = SQLITE_OK;
279         bool err = true;
280         int field_index = 1;
281
282         if (appid != NULL)
283                 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT appid FROM badge_setting WHERE uid = ? AND pkgname = ? AND appid = ?", -1, &db_statement, NULL);
284         else
285                 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT pkgname FROM badge_setting WHERE uid = ? AND pkgname = ?", -1, &db_statement, NULL);
286
287         if (sqlite3_ret != SQLITE_OK) {
288                 ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret,
289                                         sqlite3_errmsg(db));
290                 err = false;
291                 goto out;
292         }
293
294         sqlite3_bind_int(db_statement, field_index++, uid);
295         sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
296         if (appid != NULL)
297                 sqlite3_bind_text(db_statement, field_index++, appid, -1, SQLITE_TRANSIENT);
298
299         sqlite3_ret = sqlite3_step(db_statement);
300         if (sqlite3_ret == SQLITE_DONE) {
301                 INFO("no matched appid from pkgname found[%s][%s][%d]", pkgname, appid, sqlite3_ret);
302                 err = false;
303                 goto out;
304         }
305
306         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
307                 ERR("sqlite3_step failed [%d][%s]", sqlite3_ret,
308                                         sqlite3_errmsg(db));
309                 err = false;
310                 goto out;
311         }
312
313 out:
314         if (db_statement)
315                 sqlite3_finalize(db_statement);
316
317         return err;
318 }
319
320 static int app_info_callback(const pkgmgrinfo_appinfo_h handle, void *user_data)
321 {
322         badge_setting_info *info = (badge_setting_info *)user_data;
323         sqlite3 *db = info->db;
324         sqlite3_stmt *db_statement = NULL;
325         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
326         int field_index = 1;
327         int sqlite3_ret = SQLITE_OK;
328         char *appid = NULL;
329         char *pkgname = NULL;
330
331         pkgmgr_ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
332         if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
333                 ERR("pkgmgrinfo_appinfo_get_appid failed [%d]", pkgmgr_ret);
334                 goto out;
335         }
336
337         pkgmgr_ret = pkgmgrinfo_appinfo_get_pkgname(handle, &pkgname);
338         if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
339                 ERR("pkgmgrinfo_appinfo_get_pkgname failed [%d]", pkgmgr_ret);
340                 goto out;
341         }
342
343         if (_is_package_in_setting_table(db, pkgname, appid, info->uid) == true) {
344                 INFO("uid %d [%s] is exist", info->uid, appid);
345                 goto out;
346         }
347
348         INFO("uid %d pkgname %s [%s] will be inserted", info->uid, pkgname, appid);
349         sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO badge_setting (uid, pkgname, appid) "
350                                          "VALUES (?, ?, ?) ", -1, &db_statement, NULL);
351
352         if (sqlite3_ret != SQLITE_OK) {
353                 ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret,
354                                         sqlite3_errmsg(db));
355                 goto out;
356         }
357
358         sqlite3_bind_int(db_statement, field_index++, info->uid);
359         sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
360         sqlite3_bind_text(db_statement, field_index++, appid, -1, SQLITE_TRANSIENT);
361
362         sqlite3_ret = sqlite3_step(db_statement);
363
364         INFO("sqlite3_step returns[%d]", sqlite3_ret);
365
366         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE)
367                 ERR("sqlite3_step failed [%d][%s]", sqlite3_ret,
368                                         sqlite3_errmsg(db));
369
370 out:
371         if (db_statement)
372                 sqlite3_finalize(db_statement);
373
374         return 0;
375 }
376
377 static int package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
378 {
379         char *pkgname = NULL;
380         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
381         pkgmgrinfo_appinfo_filter_h handle = NULL;
382         badge_setting_info *info = (badge_setting_info *)user_data;
383
384         pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &pkgname);
385         if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
386                 ERR("package_info_get_package failed [%d]", pkgmgr_ret);
387                 goto out;
388         }
389
390         pkgmgr_ret = pkgmgrinfo_appinfo_filter_create(&handle);
391         if (pkgmgr_ret != PMINFO_R_OK) {
392                 ERR("pkgmgrinfo_appinfo_filter_create failed [%d]", pkgmgr_ret);
393                 goto out;
394         }
395
396         pkgmgr_ret = pkgmgrinfo_appinfo_filter_add_string(handle, PMINFO_APPINFO_PROP_APP_PACKAGE, pkgname);
397         if (pkgmgr_ret != PMINFO_R_OK) {
398                 ERR("pkgmgrinfo_appinfo_filter_add_string failed [%d]",
399                                         pkgmgr_ret);
400                 goto out;
401         }
402
403         pkgmgr_ret = pkgmgrinfo_appinfo_filter_add_bool(handle, PMINFO_APPINFO_PROP_APP_NODISPLAY, false);
404         if (pkgmgr_ret != PMINFO_R_OK) {
405                 ERR("pkgmgrinfo_appinfo_filter_add_bool failed [%d]",
406                                         pkgmgr_ret);
407                 goto out;
408         }
409
410         pkgmgr_ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, app_info_callback, info, info->uid);
411         if (pkgmgr_ret != PMINFO_R_OK) {
412                 ERR("pkgmgrinfo_pkginfo_filter_foreach_appinfo failed [%d]",
413                                         pkgmgr_ret);
414                 goto out;
415         }
416
417 out:
418         if (handle)
419                 pkgmgrinfo_appinfo_filter_destroy(handle);
420
421         return 0;
422 }
423
424 EXPORT_API int badge_setting_insert_package_for_uid(const char *pkgname, uid_t uid)
425 {
426         sqlite3 *db;
427         int ret = BADGE_ERROR_NONE;
428         int sqlite3_ret = SQLITE_OK;
429         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
430         badge_setting_info info;
431         pkgmgrinfo_pkginfo_filter_h handle = NULL;
432
433         sqlite3_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
434         if (sqlite3_ret != SQLITE_OK || db == NULL) {
435                 ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sqlite3_ret);
436                 ret = BADGE_ERROR_FROM_DB;
437                 goto out;
438         }
439
440         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
441
442         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&handle);
443         if (pkgmgr_ret != PMINFO_R_OK) {
444                 ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
445                 ret = BADGE_ERROR_FROM_DB;
446                 goto out;
447         }
448
449         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgname);
450         if (pkgmgr_ret != PMINFO_R_OK) {
451                 ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]",
452                                         pkgmgr_ret);
453                 ret = BADGE_ERROR_FROM_DB;
454                 goto out;
455         }
456
457         info.db = db;
458         info.uid = uid;
459         pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, package_info_callback, &info, uid);
460         if (pkgmgr_ret != PMINFO_R_OK) {
461                 ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]",
462                                         pkgmgr_ret);
463                 ret = BADGE_ERROR_FROM_DB;
464                 goto out;
465         }
466
467 out:
468         if (handle)
469                 pkgmgrinfo_pkginfo_filter_destroy(handle);
470         if (db) {
471                 if (ret == BADGE_ERROR_NONE)
472                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
473                 else
474                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
475
476                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
477                         WARN("db_util_close failed [%d]", sqlite3_ret);
478         }
479
480         return ret;
481 }
482
483 EXPORT_API int badge_setting_delete_package_for_uid(const char *pkgname, uid_t uid)
484 {
485         sqlite3 *db = NULL;
486         sqlite3_stmt *db_statement = NULL;
487         int ret = BADGE_ERROR_NONE;
488         int sqlite3_ret = SQLITE_OK;
489         int field_index = 1;
490         bool is_package_in_setting_table = false;
491
492         sqlite3_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
493         if (sqlite3_ret != SQLITE_OK || db == NULL) {
494                 ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sqlite3_ret);
495                 ret = BADGE_ERROR_FROM_DB;
496                 goto out;
497         }
498
499         is_package_in_setting_table = _is_package_in_setting_table(db, pkgname, NULL, uid);
500         if (is_package_in_setting_table == false) {
501                 INFO("[%s] is not exist", pkgname);
502                 goto out;
503         }
504
505         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
506
507         sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM badge_setting WHERE uid = ? AND pkgname = ? ", -1, &db_statement, NULL);
508         if (sqlite3_ret != SQLITE_OK) {
509                 ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret,
510                                         sqlite3_errmsg(db));
511                 ret = BADGE_ERROR_FROM_DB;
512                 goto out;
513         }
514
515         sqlite3_bind_int(db_statement, field_index++, uid);
516         sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
517
518         sqlite3_ret = sqlite3_step(db_statement);
519         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
520                 ERR("sqlite3_step failed [%d][%s]", sqlite3_ret,
521                                         sqlite3_errmsg(db));
522                 ret = BADGE_ERROR_FROM_DB;
523         }
524
525 out:
526         if (db_statement)
527                 sqlite3_finalize(db_statement);
528         if (db) {
529                 if (ret == BADGE_ERROR_NONE)
530                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
531                 else
532                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
533
534                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
535                         WARN("db_util_close failed [%d]", sqlite3_ret);
536         }
537
538         return ret;
539 }
540
541 EXPORT_API int badge_setting_refresh_setting_table(uid_t uid)
542 {
543         int ret = BADGE_ERROR_NONE;
544         int sql_ret;
545         int pkgmgr_ret;
546         sqlite3 *db = NULL;
547         badge_setting_info info;
548         pkgmgrinfo_pkginfo_filter_h filter;
549
550         sql_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
551         if (sql_ret != SQLITE_OK || db == NULL) {
552                 ERR("sqlite3_open_v2 fail [%s][%d]", BADGE_DB_PATH, sql_ret);
553                 return BADGE_ERROR_FROM_DB;
554         }
555
556         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
557
558         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
559         if (pkgmgr_ret != PMINFO_R_OK) {
560                 ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
561                 ret = BADGE_ERROR_FROM_DB;
562                 goto out;
563         }
564
565         info.db = db;
566         info.uid = uid;
567         pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, package_info_callback, &info, uid);
568         if (pkgmgr_ret != PMINFO_R_OK) {
569                 ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]",
570                                         pkgmgr_ret);
571                 ret = BADGE_ERROR_FROM_DB;
572                 goto out;
573         }
574
575 out:
576         if (filter)
577                 pkgmgrinfo_pkginfo_filter_destroy(filter);
578         if (db) {
579                 if (ret == BADGE_ERROR_NONE)
580                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
581                 else
582                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
583                 if ((sql_ret = db_util_close(db)) != SQLITE_OK)
584                         WARN("fail to db_util_close [%d]", sql_ret);
585         }
586
587         return ret;
588 }
589