Delete unnecessary line
[platform/core/appfw/badge.git] / src / badge_setting_service.c
1 /*
2  * Copyright (c) 2016 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("fail 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, sql_query);
129                 ret = BADGE_ERROR_FROM_DB;
130                 goto out;
131         }
132
133         if (!row_count) {
134                 DBG("No setting found for [%s]", appid);
135                 ret = BADGE_ERROR_NOT_EXIST;
136                 goto out;
137         }
138
139         result_setting = (struct badge_setting *)malloc(sizeof(struct badge_setting));
140         if (result_setting == NULL) {
141                 ERR("fail to alloc setting");
142                 ret = BADGE_ERROR_OUT_OF_MEMORY;
143                 goto out;
144         }
145
146         col_index = col_count;
147
148         _get_table_field_data_string(query_result, &(result_setting[0].pkgname), 1, col_index++);
149         _get_table_field_data_string(query_result, &(result_setting[0].appid), 1, col_index++);
150         _get_table_field_data_int(query_result, (int *)&(result_setting[0].allow_to_display), col_index++);
151
152         *setting = result_setting;
153
154 out:
155         if (query_result)
156                 sqlite3_free_table(query_result);
157         if (sql_query)
158                 sqlite3_free(sql_query);
159         if (db) {
160                 sql_ret = db_util_close(db);
161                 if (sql_ret != SQLITE_OK)
162                         WARN("fail to db_util_close");
163         }
164
165         return ret;
166 }
167
168 EXPORT_API int badge_db_update_setting(char *pkgname, char *appid, int allow_to_display, uid_t uid)
169 {
170         int ret = BADGE_ERROR_NONE;
171         sqlite3 *db = NULL;
172         char *sqlbuf = NULL;
173         int sql_ret;
174
175         if (pkgname == NULL || appid == NULL) {
176                 ERR("Invalid package name or app id");
177                 return BADGE_ERROR_INVALID_PARAMETER;
178         }
179
180         sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
181         if (sql_ret != SQLITE_OK || db == NULL) {
182                 ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sql_ret);
183                 return BADGE_ERROR_FROM_DB;
184         }
185
186         sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_display = %d " \
187                                 "WHERE pkgname = %Q AND appid = %Q " \
188                                 "AND uid = %d;",
189                                 BADGE_SETTING_DB_TABLE, allow_to_display,
190                                 pkgname, appid, uid);
191
192         if (!sqlbuf) {
193                 ERR("fail to alloc query");
194                 ret = BADGE_ERROR_FROM_DB;
195                 goto out;
196         }
197
198         ret = badge_db_exec(db, sqlbuf, NULL);
199
200 out:
201         if (sqlbuf)
202                 sqlite3_free(sqlbuf);
203         if (db) {
204                 sql_ret = db_util_close(db);
205                 if (sql_ret != SQLITE_OK)
206                         WARN("fail to db_util_close");
207         }
208
209         return ret;
210 }
211
212 EXPORT_API int badge_db_get_allow_to_display_by_appid(char *appid, int *allow_to_display, uid_t uid)
213 {
214         int ret = BADGE_ERROR_NONE;
215         int sql_ret;
216         int row_count;
217         int col_count;
218         int col_index;
219         char *sql_query = NULL;
220         char **query_result = NULL;
221         sqlite3 *db = NULL;
222
223         if (appid == NULL)
224                 return BADGE_ERROR_INVALID_PARAMETER;
225
226         sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
227         if (sql_ret != SQLITE_OK || db == NULL) {
228                 ERR("Failed db util open [%s][%d]", BADGE_DB_PATH, sql_ret);
229                 return BADGE_ERROR_FROM_DB;
230         }
231
232         sql_query = sqlite3_mprintf("SELECT allow_to_display FROM %s WHERE appid = %Q " \
233                                 "AND (uid = %d OR uid = %d) ORDER BY uid DESC;",
234                                 BADGE_SETTING_DB_TABLE, appid, uid,
235                                 tzplatform_getuid(TZ_SYS_GLOBALAPP_USER));
236         if (!sql_query) {
237                 ERR("fail to alloc query");
238                 ret = BADGE_ERROR_FROM_DB;
239                 goto out;
240         }
241
242         sql_ret = sqlite3_get_table(db, sql_query, &query_result, &row_count, &col_count, NULL);
243         if (sql_ret != SQLITE_OK && sql_ret != -1) {
244                 ERR("sqlite3_get_table failed [%d][%s]", sql_ret, sql_query);
245                 ret = BADGE_ERROR_FROM_DB;
246                 goto out;
247         }
248
249         if (!row_count) {
250                 DBG("No setting found for [%s]", appid);
251                 ret = BADGE_ERROR_NOT_EXIST;
252                 goto out;
253         }
254
255         col_index = col_count;
256
257         _get_table_field_data_int(query_result, (int *)allow_to_display, col_index++);
258
259 out:
260         if (query_result)
261                 sqlite3_free_table(query_result);
262         if (sql_query)
263                 sqlite3_free(sql_query);
264         if (db) {
265                 sql_ret = db_util_close(db);
266                 if (sql_ret != SQLITE_OK)
267                         WARN("fail to db_util_close");
268         }
269
270         return ret;
271 }
272
273 static bool _is_package_in_setting_table(sqlite3 *db, const char *pkgname, const char* appid, uid_t uid)
274 {
275         sqlite3_stmt *db_statement = NULL;
276         int sqlite3_ret = SQLITE_OK;
277         bool err = true;
278         int field_index = 1;
279
280         if (appid != NULL)
281                 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT appid FROM badge_setting WHERE uid = ? AND pkgname = ? AND appid = ?", -1, &db_statement, NULL);
282         else
283                 sqlite3_ret = sqlite3_prepare_v2(db, "SELECT pkgname FROM badge_setting WHERE uid = ? AND pkgname = ?", -1, &db_statement, NULL);
284
285         if (sqlite3_ret != SQLITE_OK) {
286                 ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
287                 err = false;
288                 goto out;
289         }
290
291         sqlite3_bind_int(db_statement, field_index++, uid);
292         sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
293         if (appid != NULL)
294                 sqlite3_bind_text(db_statement, field_index++, appid, -1, SQLITE_TRANSIENT);
295
296         sqlite3_ret = sqlite3_step(db_statement);
297         if (sqlite3_ret == SQLITE_DONE) {
298                 INFO("no matched appid from pkgname found[%s][%s][%d]", pkgname, appid, sqlite3_ret);
299                 err = false;
300                 goto out;
301         }
302
303         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
304                 ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
305                 err = false;
306                 goto out;
307         }
308
309 out:
310         if (db_statement)
311                 sqlite3_finalize(db_statement);
312
313         return err;
314 }
315
316 static int app_info_callback(const pkgmgrinfo_appinfo_h handle, void *user_data)
317 {
318         badge_setting_info *info = (badge_setting_info *)user_data;
319         sqlite3 *db = info->db;
320         sqlite3_stmt *db_statement = NULL;
321         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
322         int field_index = 1;
323         int sqlite3_ret = SQLITE_OK;
324         char *appid = NULL;
325         char *pkgname = NULL;
326
327         pkgmgr_ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
328         if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
329                 ERR("pkgmgrinfo_appinfo_get_appid failed [%d]", pkgmgr_ret);
330                 goto out;
331         }
332
333         pkgmgr_ret = pkgmgrinfo_appinfo_get_pkgname(handle, &pkgname);
334         if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
335                 ERR("pkgmgrinfo_appinfo_get_pkgname failed [%d]", pkgmgr_ret);
336                 goto out;
337         }
338
339         if (_is_package_in_setting_table(db, pkgname, appid, info->uid) == true) {
340                 INFO("uid %d [%s] is exist", info->uid, appid);
341                 goto out;
342         }
343
344         INFO("uid %d pkgname %s [%s] will be inserted", info->uid, pkgname, appid);
345         sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO badge_setting (uid, pkgname, appid) "
346                                          "VALUES (?, ?, ?) ", -1, &db_statement, NULL);
347
348         if (sqlite3_ret != SQLITE_OK) {
349                 ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
350                 goto out;
351         }
352
353         sqlite3_bind_int(db_statement, field_index++, info->uid);
354         sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
355         sqlite3_bind_text(db_statement, field_index++, appid, -1, SQLITE_TRANSIENT);
356
357         sqlite3_ret = sqlite3_step(db_statement);
358
359         INFO("sqlite3_step returns[%d]", sqlite3_ret);
360
361         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE)
362                 ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
363
364 out:
365         if (db_statement)
366                 sqlite3_finalize(db_statement);
367
368         return 0;
369 }
370
371 static int package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
372 {
373         char *pkgname = NULL;
374         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
375         pkgmgrinfo_appinfo_filter_h handle = NULL;
376         badge_setting_info *info = (badge_setting_info *)user_data;
377
378         pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &pkgname);
379         if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
380                 ERR("package_info_get_package failed [%d]", pkgmgr_ret);
381                 goto out;
382         }
383
384         pkgmgr_ret = pkgmgrinfo_appinfo_filter_create(&handle);
385         if (pkgmgr_ret != PMINFO_R_OK) {
386                 ERR("pkgmgrinfo_appinfo_filter_create failed [%d]", pkgmgr_ret);
387                 goto out;
388         }
389
390         pkgmgr_ret = pkgmgrinfo_appinfo_filter_add_string(handle, PMINFO_APPINFO_PROP_APP_PACKAGE, pkgname);
391         if (pkgmgr_ret != PMINFO_R_OK) {
392                 ERR("pkgmgrinfo_appinfo_filter_add_string failed [%d]", pkgmgr_ret);
393                 goto out;
394         }
395
396         pkgmgr_ret = pkgmgrinfo_appinfo_filter_add_bool(handle, PMINFO_APPINFO_PROP_APP_NODISPLAY, false);
397         if (pkgmgr_ret != PMINFO_R_OK) {
398                 ERR("pkgmgrinfo_appinfo_filter_add_bool failed [%d]", pkgmgr_ret);
399                 goto out;
400         }
401
402         pkgmgr_ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, app_info_callback, info, info->uid);
403         if (pkgmgr_ret != PMINFO_R_OK) {
404                 ERR("pkgmgrinfo_pkginfo_filter_foreach_appinfo failed [%d]", pkgmgr_ret);
405                 goto out;
406         }
407
408 out:
409         if (handle)
410                 pkgmgrinfo_appinfo_filter_destroy(handle);
411
412         return 0;
413 }
414
415 EXPORT_API int badge_setting_insert_package_for_uid(const char *pkgname, uid_t uid)
416 {
417         sqlite3 *db;
418         int ret = BADGE_ERROR_NONE;
419         int sqlite3_ret = SQLITE_OK;
420         int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
421         badge_setting_info info;
422         pkgmgrinfo_pkginfo_filter_h handle = NULL;
423
424         sqlite3_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
425         if (sqlite3_ret != SQLITE_OK || db == NULL) {
426                 ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sqlite3_ret);
427                 ret = BADGE_ERROR_FROM_DB;
428                 goto out;
429         }
430
431         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
432
433         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&handle);
434         if (pkgmgr_ret != PMINFO_R_OK) {
435                 ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
436                 ret = BADGE_ERROR_FROM_DB;
437                 goto out;
438         }
439
440         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgname);
441         if (pkgmgr_ret != PMINFO_R_OK) {
442                 ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
443                 ret = BADGE_ERROR_FROM_DB;
444                 goto out;
445         }
446
447         info.db = db;
448         info.uid = uid;
449         pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, package_info_callback, &info, uid);
450         if (pkgmgr_ret != PMINFO_R_OK) {
451                 ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
452                 ret = BADGE_ERROR_FROM_DB;
453                 goto out;
454         }
455
456 out:
457         if (handle)
458                 pkgmgrinfo_pkginfo_filter_destroy(handle);
459         if (db) {
460                 if (ret == BADGE_ERROR_NONE)
461                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
462                 else
463                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
464
465                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
466                         WARN("db_util_close failed [%d]", sqlite3_ret);
467         }
468
469         return ret;
470 }
471
472 EXPORT_API int badge_setting_delete_package_for_uid(const char *pkgname, uid_t uid)
473 {
474         sqlite3 *db = NULL;
475         sqlite3_stmt *db_statement = NULL;
476         int ret = BADGE_ERROR_NONE;
477         int sqlite3_ret = SQLITE_OK;
478         int field_index = 1;
479         bool is_package_in_setting_table = false;
480
481         sqlite3_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
482         if (sqlite3_ret != SQLITE_OK || db == NULL) {
483                 ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sqlite3_ret);
484                 ret = BADGE_ERROR_FROM_DB;
485                 goto out;
486         }
487
488         is_package_in_setting_table = _is_package_in_setting_table(db, pkgname, NULL, uid);
489         if (is_package_in_setting_table == false) {
490                 INFO("[%s] is not exist", pkgname);
491                 goto out;
492         }
493
494         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
495
496         sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM badge_setting WHERE uid = ? AND pkgname = ? ", -1, &db_statement, NULL);
497         if (sqlite3_ret != SQLITE_OK) {
498                 ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
499                 ret = BADGE_ERROR_FROM_DB;
500                 goto out;
501         }
502
503         sqlite3_bind_int(db_statement, field_index++, uid);
504         sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
505
506         sqlite3_ret = sqlite3_step(db_statement);
507         if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
508                 ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
509                 ret = BADGE_ERROR_FROM_DB;
510         }
511
512 out:
513         if (db_statement)
514                 sqlite3_finalize(db_statement);
515         if (db) {
516                 if (ret == BADGE_ERROR_NONE)
517                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
518                 else
519                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
520
521                 if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
522                         WARN("db_util_close failed [%d]", sqlite3_ret);
523         }
524
525         return ret;
526 }
527
528 EXPORT_API int badge_setting_refresh_setting_table(uid_t uid)
529 {
530         int ret = BADGE_ERROR_NONE;
531         int sql_ret;
532         int pkgmgr_ret;
533         sqlite3 *db = NULL;
534         badge_setting_info info;
535         pkgmgrinfo_pkginfo_filter_h filter;
536
537         sql_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
538         if (sql_ret != SQLITE_OK || db == NULL) {
539                 ERR("sqlite3_open_v2 fail [%s][%d]", BADGE_DB_PATH, sql_ret);
540                 return BADGE_ERROR_FROM_DB;
541         }
542
543         sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
544
545         pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
546         if (pkgmgr_ret != PMINFO_R_OK) {
547                 ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
548                 ret = BADGE_ERROR_FROM_DB;
549                 goto out;
550         }
551
552         info.db = db;
553         info.uid = uid;
554         pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, package_info_callback, &info, uid);
555         if (pkgmgr_ret != PMINFO_R_OK) {
556                 ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
557                 ret = BADGE_ERROR_FROM_DB;
558                 goto out;
559         }
560
561 out:
562         if (filter)
563                 pkgmgrinfo_pkginfo_filter_destroy(filter);
564         if (db) {
565                 if (ret == BADGE_ERROR_NONE)
566                         sqlite3_exec(db, "END;", NULL, NULL, NULL);
567                 else
568                         sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
569                 if ((sql_ret = db_util_close(db)) != SQLITE_OK)
570                         WARN("fail to db_util_close [%d]", sql_ret);
571         }
572
573         return ret;
574 }
575