--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <sqlite3.h>
+#include <db-util.h>
+#include <gio/gio.h>
+#include <string.h>
+#include <pkgmgr-info.h>
+#include <package_manager.h>
+
+#include "badge_setting.h"
+#include "badge_setting_service.h"
+#include "badge_db.h"
+#include "badge_error.h"
+#include "badge_log.h"
+
+#define BADGE_PRIVILEGE "http://tizen.org/privilege/notification"
+
+typedef struct {
+ uid_t uid;
+ sqlite3 *db;
+} badge_setting_info;
+
+static bool _get_table_field_data_int(char **table, int *buf, int index)
+{
+ if (table == NULL || buf == NULL || index < 0) {
+ /* LCOV_EXCL_START */
+ ERR("table[%p], buf[%p], index[%d]", table, buf, index);
+ return false;
+ /* LCOV_EXCL_STOP */
+ }
+
+ if (table[index] != NULL) {
+ *buf = atoi(table[index]);
+ return true;
+ }
+
+ /* LCOV_EXCL_START */
+ *buf = 0;
+ return false;
+ /* LCOV_EXCL_STOP */
+}
+
+static bool _get_table_field_data_string(char **table, char **buf, int ucs2, int index)
+{
+ bool ret = false;
+ int sLen = 0;
+ char *pTemp;
+
+ if (table == NULL || buf == NULL || index < 0) {
+ /* LCOV_EXCL_START */
+ ERR("table[%p], buf[%p], index[%d]", table, buf, index);
+ return false;
+ /* LCOV_EXCL_STOP */
+ }
+
+ pTemp = table[index];
+ if (pTemp == NULL) {
+ *buf = NULL; /* LCOV_EXCL_LINE */
+ } else {
+ sLen = strlen(pTemp);
+ if (sLen) {
+ *buf = (char *)malloc(sLen + 1);
+ if (*buf == NULL) {
+ ERR("malloc is failed"); /* LCOV_EXCL_LINE */
+ goto out;
+ }
+ memset(*buf, 0, sLen + 1);
+ strncpy(*buf, pTemp, sLen);
+ } else {
+ *buf = NULL; /* LCOV_EXCL_LINE */
+ }
+ }
+
+ ret = true;
+
+out:
+ return ret;
+}
+
+EXPORT_API int badge_db_get_setting_by_appid(const char *appid, badge_setting_h *setting, uid_t uid)
+{
+ int ret = BADGE_ERROR_NONE;
+ int sql_ret;
+ int row_count;
+ int col_count;
+ int col_index;
+ char *sql_query = NULL;
+ char **query_result = NULL;
+ badge_setting_h result_setting;
+ sqlite3 *db = NULL;
+
+ if (appid == NULL)
+ return BADGE_ERROR_INVALID_PARAMETER;
+
+ sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
+ if (sql_ret != SQLITE_OK || db == NULL) {
+ ERR("Failed db util open [%s][%d]", BADGE_DB_PATH, sql_ret);
+ return BADGE_ERROR_FROM_DB;
+ }
+
+ sql_query = sqlite3_mprintf("SELECT pkgname, appid, allow_to_display FROM %s WHERE appid = %Q AND uid = %d",
+ BADGE_SETTING_DB_TABLE, appid, uid);
+ if (!sql_query) {
+ ERR("fail to alloc query");
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ sql_ret = sqlite3_get_table(db, sql_query, &query_result, &row_count, &col_count, NULL);
+ if (sql_ret != SQLITE_OK && sql_ret != -1) {
+ ERR("sqlite3_get_table failed [%d][%s]", sql_ret, sql_query);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ if (!row_count) {
+ DBG("No setting found for [%s]", appid);
+ ret = BADGE_ERROR_NOT_EXIST;
+ goto out;
+ }
+
+ result_setting = (struct badge_setting *)malloc(sizeof(struct badge_setting));
+ if (result_setting == NULL) {
+ ERR("fail to alloc setting");
+ ret = BADGE_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ col_index = col_count;
+
+ _get_table_field_data_string(query_result, &(result_setting[0].pkgname), 1, col_index++);
+ _get_table_field_data_string(query_result, &(result_setting[0].appid), 1, col_index++);
+ _get_table_field_data_int(query_result, (int *)&(result_setting[0].allow_to_display), col_index++);
+
+ *setting = result_setting;
+
+out:
+ if (query_result)
+ sqlite3_free_table(query_result);
+ if (sql_query)
+ sqlite3_free(sql_query);
+ if (db) {
+ sql_ret = db_util_close(db);
+ if (sql_ret != SQLITE_OK)
+ WARN("fail to db_util_close");
+ }
+
+ return ret;
+}
+
+EXPORT_API int badge_db_update_setting(char *pkgname, char *appid, int allow_to_display, uid_t uid)
+{
+ int ret = BADGE_ERROR_NONE;
+ sqlite3 *db = NULL;
+ char *sqlbuf = NULL;
+ int sql_ret;
+
+ if (pkgname == NULL || appid == NULL) {
+ ERR("Invalid package name or app id");
+ return BADGE_ERROR_INVALID_PARAMETER;
+ }
+
+ sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
+ if (sql_ret != SQLITE_OK || db == NULL) {
+ ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sql_ret);
+ return BADGE_ERROR_FROM_DB;
+ }
+
+ sqlbuf = sqlite3_mprintf("UPDATE %s SET allow_to_display = %d " \
+ "WHERE pkgname = %Q AND appid = %Q AND uid = %d",
+ BADGE_SETTING_DB_TABLE, allow_to_display, pkgname, appid, uid);
+
+ if (!sqlbuf) {
+ ERR("fail to alloc query");
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ ret = badge_db_exec(db, sqlbuf, NULL);
+
+out:
+ if (sqlbuf)
+ sqlite3_free(sqlbuf);
+ if (db) {
+ sql_ret = db_util_close(db);
+ if (sql_ret != SQLITE_OK)
+ WARN("fail to db_util_close");
+ }
+
+ return ret;
+}
+
+EXPORT_API int badge_db_get_allow_to_display_by_appid(char *appid, int *allow_to_display, uid_t uid)
+{
+ int ret = BADGE_ERROR_NONE;
+ int sql_ret;
+ int row_count;
+ int col_count;
+ int col_index;
+ char *sql_query = NULL;
+ char **query_result = NULL;
+ sqlite3 *db = NULL;
+
+ if (appid == NULL)
+ return BADGE_ERROR_INVALID_PARAMETER;
+
+ sql_ret = db_util_open(BADGE_DB_PATH, &db, 0);
+ if (sql_ret != SQLITE_OK || db == NULL) {
+ ERR("Failed db util open [%s][%d]", BADGE_DB_PATH, sql_ret);
+ return BADGE_ERROR_FROM_DB;
+ }
+
+ sql_query = sqlite3_mprintf("SELECT allow_to_display FROM %s WHERE appid = %Q AND uid = %d",
+ BADGE_SETTING_DB_TABLE, appid, uid);
+ if (!sql_query) {
+ ERR("fail to alloc query");
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ sql_ret = sqlite3_get_table(db, sql_query, &query_result, &row_count, &col_count, NULL);
+ if (sql_ret != SQLITE_OK && sql_ret != -1) {
+ ERR("sqlite3_get_table failed [%d][%s]", sql_ret, sql_query);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ if (!row_count) {
+ DBG("No setting found for [%s]", appid);
+ ret = BADGE_ERROR_NOT_EXIST;
+ goto out;
+ }
+
+ col_index = col_count;
+
+ _get_table_field_data_int(query_result, (int *)allow_to_display, col_index++);
+
+out:
+ if (query_result)
+ sqlite3_free_table(query_result);
+ if (sql_query)
+ sqlite3_free(sql_query);
+ if (db) {
+ sql_ret = db_util_close(db);
+ if (sql_ret != SQLITE_OK)
+ WARN("fail to db_util_close");
+ }
+
+ return ret;
+}
+
+static bool _is_package_in_setting_table(sqlite3 *db, const char *pkgname, const char* appid, uid_t uid)
+{
+ sqlite3_stmt *db_statement = NULL;
+ int sqlite3_ret = SQLITE_OK;
+ bool err = true;
+ int field_index = 1;
+
+ if (appid != NULL)
+ sqlite3_ret = sqlite3_prepare_v2(db, "SELECT appid FROM badge_setting WHERE uid = ? AND pkgname = ? AND appid = ?", -1, &db_statement, NULL);
+ else
+ sqlite3_ret = sqlite3_prepare_v2(db, "SELECT pkgname FROM badge_setting WHERE uid = ? AND pkgname = ?", -1, &db_statement, NULL);
+
+ if (sqlite3_ret != SQLITE_OK) {
+ ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+ err = false;
+ goto out;
+ }
+
+ sqlite3_bind_int(db_statement, field_index++, uid);
+ sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
+ if (appid != NULL)
+ sqlite3_bind_text(db_statement, field_index++, appid, -1, SQLITE_TRANSIENT);
+
+ sqlite3_ret = sqlite3_step(db_statement);
+ if (sqlite3_ret == SQLITE_DONE) {
+ INFO("no matched appid from pkgname found[%s][%s][%d]", pkgname, appid, sqlite3_ret);
+ err = false;
+ goto out;
+ }
+
+ if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_ROW) {
+ ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+ err = false;
+ goto out;
+ }
+
+out:
+ if (db_statement)
+ sqlite3_finalize(db_statement);
+
+ return err;
+}
+
+static int app_info_callback(const pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+ badge_setting_info *info = (badge_setting_info *)user_data;
+ sqlite3 *db = info->db;
+ sqlite3_stmt *db_statement = NULL;
+ int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
+ int field_index = 1;
+ int sqlite3_ret = SQLITE_OK;
+ char *appid = NULL;
+ char *pkgname = NULL;
+
+ pkgmgr_ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
+ ERR("pkgmgrinfo_appinfo_get_appid failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+ pkgmgr_ret = pkgmgrinfo_appinfo_get_pkgname(handle, &pkgname);
+ if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
+ ERR("pkgmgrinfo_appinfo_get_pkgname failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+ if (_is_package_in_setting_table(db, pkgname, appid, info->uid) == true) {
+ INFO("uid %d [%s] is exist", info->uid, appid);
+ goto out;
+ }
+
+ INFO("uid %d pkgname %s [%s] will be inserted", info->uid, pkgname, appid);
+ sqlite3_ret = sqlite3_prepare_v2(db, "INSERT INTO badge_setting (uid, pkgname, appid) "
+ "VALUES (?, ?, ?) ", -1, &db_statement, NULL);
+
+ if (sqlite3_ret != SQLITE_OK) {
+ ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+ goto out;
+ }
+
+ sqlite3_bind_int(db_statement, field_index++, info->uid);
+ sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(db_statement, field_index++, appid, -1, SQLITE_TRANSIENT);
+
+ sqlite3_ret = sqlite3_step(db_statement);
+
+ INFO("sqlite3_step returns[%d]", sqlite3_ret);
+
+ if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE)
+ ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+
+out:
+ if (db_statement)
+ sqlite3_finalize(db_statement);
+
+ return 0;
+}
+
+static int package_info_callback(const pkgmgrinfo_pkginfo_h package_info, void *user_data)
+{
+ char *pkgname = NULL;
+ int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
+ pkgmgrinfo_appinfo_filter_h handle = NULL;
+ badge_setting_info *info = (badge_setting_info *)user_data;
+
+ pkgmgr_ret = pkgmgrinfo_pkginfo_get_pkgname(package_info, &pkgname);
+ if (pkgmgr_ret != PACKAGE_MANAGER_ERROR_NONE) {
+ ERR("package_info_get_package failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+ pkgmgr_ret = pkgmgrinfo_appinfo_filter_create(&handle);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_appinfo_filter_create failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+ pkgmgr_ret = pkgmgrinfo_appinfo_filter_add_string(handle, PMINFO_APPINFO_PROP_APP_PACKAGE, pkgname);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_appinfo_filter_add_string failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+ pkgmgr_ret = pkgmgrinfo_appinfo_filter_add_bool(handle, PMINFO_APPINFO_PROP_APP_NODISPLAY, false);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_appinfo_filter_add_bool failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+ pkgmgr_ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, app_info_callback, info, info->uid);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_pkginfo_filter_foreach_appinfo failed [%d]", pkgmgr_ret);
+ goto out;
+ }
+
+out:
+ if (handle)
+ pkgmgrinfo_appinfo_filter_destroy(handle);
+
+ return 0;
+}
+
+
+EXPORT_API int badge_setting_insert_package_for_uid(const char *pkgname, uid_t uid)
+{
+ sqlite3 *db;
+ int ret = BADGE_ERROR_NONE;
+ int sqlite3_ret = SQLITE_OK;
+ int pkgmgr_ret = PACKAGE_MANAGER_ERROR_NONE;
+ badge_setting_info info;
+ pkgmgrinfo_pkginfo_filter_h handle = NULL;
+
+ sqlite3_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
+ if (sqlite3_ret != SQLITE_OK || db == NULL) {
+ ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sqlite3_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
+
+ pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&handle);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ pkgmgr_ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgname);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_pkginfo_filter_add_string failed [%d]", pkgmgr_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ info.db = db;
+ info.uid = uid;
+ pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, package_info_callback, &info, uid);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+out:
+ if (handle)
+ pkgmgrinfo_pkginfo_filter_destroy(handle);
+ if (db) {
+ if (ret == BADGE_ERROR_NONE)
+ sqlite3_exec(db, "END;", NULL, NULL, NULL);
+ else
+ sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
+
+ if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
+ WARN("db_util_close failed [%d]", sqlite3_ret);
+ }
+
+ return ret;
+}
+
+EXPORT_API int badge_setting_delete_package_for_uid(const char *pkgname, uid_t uid)
+{
+ sqlite3 *db = NULL;
+ sqlite3_stmt *db_statement = NULL;
+ int ret = BADGE_ERROR_NONE;
+ int sqlite3_ret = SQLITE_OK;
+ int field_index = 1;
+ bool is_package_in_setting_table = false;
+
+ sqlite3_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
+ if (sqlite3_ret != SQLITE_OK || db == NULL) {
+ ERR("db_util_open failed [%s][%d]", BADGE_DB_PATH, sqlite3_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ is_package_in_setting_table = _is_package_in_setting_table(db, pkgname, NULL, uid);
+ if (is_package_in_setting_table == false) {
+ INFO("[%s] is not exist", pkgname);
+ goto out;
+ }
+
+ sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
+
+ sqlite3_ret = sqlite3_prepare_v2(db, "DELETE FROM badge_setting WHERE uid = ? AND pkgname = ? ", -1, &db_statement, NULL);
+ if (sqlite3_ret != SQLITE_OK) {
+ ERR("sqlite3_prepare_v2 failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ sqlite3_bind_int(db_statement, field_index++, uid);
+ sqlite3_bind_text(db_statement, field_index++, pkgname, -1, SQLITE_TRANSIENT);
+
+ sqlite3_ret = sqlite3_step(db_statement);
+ if (sqlite3_ret != SQLITE_OK && sqlite3_ret != SQLITE_DONE) {
+ ERR("sqlite3_step failed [%d][%s]", sqlite3_ret, sqlite3_errmsg(db));
+ ret = BADGE_ERROR_FROM_DB;
+ }
+
+out:
+ if (db_statement)
+ sqlite3_finalize(db_statement);
+ if (db) {
+ if (ret == BADGE_ERROR_NONE)
+ sqlite3_exec(db, "END;", NULL, NULL, NULL);
+ else
+ sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
+
+ if ((sqlite3_ret = db_util_close(db)) != SQLITE_OK)
+ WARN("db_util_close failed [%d]", sqlite3_ret);
+ }
+
+ return ret;
+}
+
+EXPORT_API int badge_setting_refresh_setting_table(uid_t uid)
+{
+ int ret = BADGE_ERROR_NONE;
+ int sql_ret;
+ int pkgmgr_ret;
+ sqlite3 *db = NULL;
+ badge_setting_info info;
+ pkgmgrinfo_pkginfo_filter_h filter;
+
+ sql_ret = sqlite3_open_v2(BADGE_DB_PATH, &db, SQLITE_OPEN_READWRITE, NULL);
+ if (sql_ret != SQLITE_OK || db == NULL) {
+ ERR("sqlite3_open_v2 fail [%s][%d]", BADGE_DB_PATH, sql_ret);
+ return BADGE_ERROR_FROM_DB;
+ }
+
+ sqlite3_exec(db, "BEGIN immediate;", NULL, NULL, NULL);
+
+ pkgmgr_ret = pkgmgrinfo_pkginfo_filter_create(&filter);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_pkginfo_filter_create failed [%d]", pkgmgr_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+ info.db = db;
+ info.uid = uid;
+ pkgmgr_ret = pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(filter, package_info_callback, &info, uid);
+ if (pkgmgr_ret != PMINFO_R_OK) {
+ ERR("pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo failed [%d]", pkgmgr_ret);
+ ret = BADGE_ERROR_FROM_DB;
+ goto out;
+ }
+
+out:
+ if (filter)
+ pkgmgrinfo_pkginfo_filter_destroy(filter);
+ if (db) {
+ if (ret == BADGE_ERROR_NONE)
+ sqlite3_exec(db, "END;", NULL, NULL, NULL);
+ else
+ sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
+ if ((sql_ret = db_util_close(db)) != SQLITE_OK)
+ WARN("fail to db_util_close [%d]", sql_ret);
+ }
+
+ return ret;
+}
+