Adds APIs for Application detail setting 78/99478/8 accepted/tizen/3.0/common/20161130.133529 accepted/tizen/3.0/ivi/20161130.091040 accepted/tizen/3.0/mobile/20161130.090946 accepted/tizen/3.0/tv/20161130.091001 accepted/tizen/3.0/wearable/20161130.091020 submit/tizen_3.0/20161130.022513
authorseungha.son <seungha.son@samsung.com>
Tue, 18 Oct 2016 13:54:27 +0000 (22:54 +0900)
committerseungha.son <seungha.son@samsung.com>
Tue, 29 Nov 2016 10:02:37 +0000 (19:02 +0900)
 - Init badge setting db.
 - Implement APIs related badge setting.
 - Implement logic for setting db

Signed-off-by: seungha.son <seungha.son@samsung.com>
Change-Id: I9aafb8d9661b316cffaedca9ed5051f3bee355f5

14 files changed:
11_badge-add.post [new file with mode: 0644]
CMakeLists.txt
include/badge.h
include/badge_db.h
include/badge_ipc.h
include/badge_setting.h [new file with mode: 0644]
include/badge_setting_service.h [new file with mode: 0644]
packaging/badge.spec
src/badge_db.c
src/badge_init.c [new file with mode: 0644]
src/badge_internal.c
src/badge_ipc.c
src/badge_setting.c [new file with mode: 0644]
src/badge_setting_service.c [new file with mode: 0644]

diff --git a/11_badge-add.post b/11_badge-add.post
new file mode 100644 (file)
index 0000000..f535dc4
--- /dev/null
@@ -0,0 +1 @@
+badge_init --uid $2
index 1be439a..d7c024a 100755 (executable)
@@ -17,6 +17,13 @@ SET(INSTALL_HEADERS_DEVEL
        badge_error.h
        badge_internal.h
        badge_db.h
+       badge_setting.h
+       badge_setting_service.h
+       badge_ipc.h
+)
+
+SET(INIT-SRCS
+       src/badge_init.c
 )
 
 SET(SRCS
@@ -25,6 +32,8 @@ SET(SRCS
        src/badge_db.c
        src/badge_ipc.c
        src/badge_internal.c
+       src/badge_setting.c
+       src/badge_setting_service.c
 )
 
 SET(SUBMODULES_DEVEL
@@ -43,6 +52,7 @@ pkg_check_modules(pkgs REQUIRED
        capi-appfw-package-manager
        db-util
        libtzplatform-config
+       pkgmgr-info
 )
 
 FOREACH(flag ${pkgs_CFLAGS})
@@ -61,6 +71,9 @@ SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
 SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
 
+ADD_EXECUTABLE(badge_init ${INIT-SRCS})
+TARGET_LINK_LIBRARIES(badge_init ${pkgs_LDFLAGS} badge)
+
 MESSAGE(${LIB_INSTALL_DIR} ====)
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
 
@@ -72,3 +85,5 @@ FOREACH(hfile ${INSTALL_HEADERS_DEVEL})
        INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/${hfile} DESTINATION include/${PROJECT_NAME})
 ENDFOREACH(hfile)
 
+INSTALL(FILES ${CMAKE_BINARY_DIR}/11_badge-add.post DESTINATION ${SYSCONF_INSTALL_DIR}/gumd/useradd.d/)
+INSTALL(TARGETS badge_init DESTINATION bin)
index 45a961b..2eaf7d2 100755 (executable)
@@ -324,6 +324,8 @@ typedef void (*badge_change_cb)(unsigned int action, const char *app_id,
                        unsigned int count, void *user_data);
 /**
  * @brief Registers a callback function to receive badge change event.
+ * @remarks Should be used in the homescreen.\n
+ * Prospective Clients : Homescreen.
  * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif
  * @privlevel public
  * @privilege %http://tizen.org/privilege/notification
index 69564ae..b8ad800 100755 (executable)
 #include <stdbool.h>
 #include <sqlite3.h>
 #include <sys/types.h>
+#include <gio/gio.h>
+#include <tzplatform_config.h>
 #include <badge_error.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define BADGE_DB_PATH tzplatform_mkpath(TZ_SYS_DB, ".badge.db")
+#define BADGE_SETTING_DB_TABLE "badge_setting"
+
 int badge_db_insert(const char *pkgname, const char *writable_pkg, const char *caller, uid_t uid);
 int badge_db_delete(const char *pkgname, const char *caller_pkg, uid_t uid);
 int badge_db_set_count(const char *pkgname, const char *caller_pkg, unsigned int count, uid_t uid);
index 0d61147..29c3d8f 100755 (executable)
@@ -19,7 +19,9 @@
 #define __BADGE_IPC_H__
 
 #include <badge.h>
+#include <badge_setting.h>
 #include <sys/types.h>
+#include <glib.h>
 
 #define BADGE_ADDR "/tmp/.badge.service"
 
@@ -46,6 +48,13 @@ int badge_ipc_del_deferred_task(void (*badge_add_deferred_task)(void *data));
 int badge_ipc_request_get_list(badge_foreach_cb callback, void *data, uid_t uid);
 int badge_ipc_request_is_existing(const char *pkgname, bool *existing, uid_t uid);
 
+int badge_ipc_request_update_setting(badge_setting_h setting, uid_t uid);
+int badge_ipc_request_get_setting_by_appid(badge_setting_h *setting, const char *appid, uid_t uid);
+int badge_ipc_init_badge(uid_t uid);
+
+GVariant *badge_ipc_make_gvariant_from_setting(badge_setting_h setting);
+int badge_ipc_make_setting_from_gvariant(badge_setting_h setting, GVariant *variant);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/badge_setting.h b/include/badge_setting.h
new file mode 100644 (file)
index 0000000..73010b6
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef __BADGE_SETTING_H__
+#define __BADGE_SETTING_H__
+
+#include <stdbool.h>
+#include <sys/types.h>
+#include "badge_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /*  __cplusplus */
+
+/**
+ * @file badge_setting.h
+ * @brief This file contains the badge APIs.
+ */
+
+/**
+ * @addtogroup BADGE_MODULE
+ * @{
+ */
+
+typedef struct badge_setting *badge_setting_h;
+
+struct badge_setting {
+       char *pkgname;
+       char *appid;
+       int allow_to_display;
+};
+
+int badge_setting_get_pkgname(badge_setting_h setting, char **pkgname);
+int badge_setting_get_appid(badge_setting_h setting, char **appid);
+int badge_setting_set_allow_to_display(badge_setting_h setting, bool value);
+int badge_setting_get_allow_to_display(badge_setting_h setting, bool *value);
+int badge_setting_update_setting(badge_setting_h setting);
+int badge_setting_update_setting_for_uid(badge_setting_h setting, uid_t uid);
+int badge_setting_get_setting_by_appid(badge_setting_h *setting, const char *appid);
+int badge_setting_get_setting_by_appid_for_uid(badge_setting_h *setting, const char *appid, uid_t uid);
+int badge_setting_free_setting(badge_setting_h setting);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BADGE_SETTING_H__ */
diff --git a/include/badge_setting_service.h b/include/badge_setting_service.h
new file mode 100644 (file)
index 0000000..de97921
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef __BADGE_SETTING_SERVICE_H__
+#define __BADGE_SETTING_SERVICE_H__
+
+#include <stdbool.h>
+#include <sys/types.h>
+#include "badge_error.h"
+#include "badge_setting.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /*  __cplusplus */
+
+/**
+ * @file badge_setting_service.h
+ * @brief This file contains the badge APIs.
+ */
+
+/**
+ * @addtogroup BADGE_MODULE
+ * @{
+ */
+
+int badge_db_get_setting_by_appid(const char *appid, badge_setting_h *setting, uid_t uid);
+int badge_db_get_allow_to_display_by_appid(char *appid, int *allow_to_display, uid_t uid);
+int badge_setting_insert_package_for_uid(const char *pkgname, uid_t uid);
+int badge_setting_delete_package_for_uid(const char *pkgname, uid_t uid);
+int badge_setting_refresh_setting_table(uid_t uid);
+int badge_db_update_setting(char *pkgname, char *appid, int allow_to_display, uid_t uid);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __BADGE_SETTING_SERVICE_H__ */
+
index 836e2a6..7645079 100755 (executable)
@@ -13,6 +13,7 @@ BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(capi-appfw-package-manager)
 BuildRequires: pkgconfig(db-util)
 BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: cmake
 Requires(post): /sbin/ldconfig
 requires(postun): /sbin/ldconfig
@@ -73,6 +74,11 @@ fi
 %{_includedir}/badge/badge.h
 %{_includedir}/badge/badge_error.h
 %{_includedir}/badge/badge_internal.h
+%{_includedir}/badge/badge_setting.h
+%{_includedir}/badge/badge_setting_service.h
+%{_includedir}/badge/badge_ipc.h
+%attr(755,root,root) %{_sysconfdir}/gumd/useradd.d/11_badge-add.post
+%{_bindir}/badge_init
 %{upgrade_script_path}/106.badge_upgrade.sh
 
 %files devel
@@ -81,4 +87,7 @@ fi
 %{_includedir}/badge/badge_error.h
 %{_includedir}/badge/badge_internal.h
 %{_includedir}/badge/badge_db.h
+%{_includedir}/badge/badge_setting.h
+%{_includedir}/badge/badge_setting_service.h
+%{_includedir}/badge/badge_ipc.h
 %{_libdir}/pkgconfig/%{name}.pc
index 2bd18c3..5056a8c 100755 (executable)
 #include <stdlib.h>
 #include <stdarg.h>
 #include <sqlite3.h>
-#include <tzplatform_config.h>
 #include <db-util.h>
 
 #include "badge.h"
+#include "badge_db.h"
 #include "badge_log.h"
 #include "badge_error.h"
 #include "badge_internal.h"
@@ -44,6 +44,13 @@ create table if not exists badge_option ( \
        pkgname TEXT NOT NULL, \
        display INTEGER default 1, \
        UNIQUE (uid, pkgname) \
+); \
+create table if not exists badge_setting ( \
+       uid INTEGER, \
+       pkgname TEXT NOT NULL, \
+       appid TEXT NOT NULL, \
+       allow_to_display INTEGER default 1, \
+       UNIQUE (uid, pkgname, appid) \
 ); "
 
 EXPORT_API
diff --git a/src/badge_init.c b/src/badge_init.c
new file mode 100644 (file)
index 0000000..f0b53d9
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+#include <badge_setting.h>
+#include <badge_setting_service.h>
+#include <badge_error.h>
+
+#define OWNER_ROOT 0
+
+#ifdef _E
+#undef _E
+#endif
+#define _E(fmt, arg...) fprintf(stderr, "[BADGE_INIT][E][%s,%d] "fmt"\n", \
+                               __FUNCTION__, __LINE__, ##arg);
+
+static int __is_authorized(void)
+{
+       uid_t uid = getuid();
+
+       if ((uid_t)OWNER_ROOT == uid)
+               return 1;
+       else
+               return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret;
+       uid_t uid = OWNER_ROOT;
+
+       if (!__is_authorized()) {
+               _E("You are not an authorized user!");
+               return -1;
+       }
+
+       if (argc > 2)
+               uid = (uid_t)atoi(argv[2]);
+
+       ret = badge_setting_refresh_setting_table(uid);
+       if (ret != BADGE_ERROR_NONE)
+               _E("badge setting table refresh fail.");
+
+       return ret;
+}
index d57946f..e6eceda 100755 (executable)
@@ -36,8 +36,6 @@
 #include "badge_ipc.h"
 #include "badge_db.h"
 
-#define BADGE_DB_PATH tzplatform_mkpath(TZ_SYS_DB, ".badge.db")
-
 #define BADGE_PKGNAME_LEN 512
 #define BADGE_TABLE_NAME "badge_data"
 #define BADGE_OPTION_TABLE_NAME "badge_option"
@@ -1119,7 +1117,11 @@ int _badge_register_changed_cb(badge_change_cb callback, void *data, uid_t uid)
        }
 
        ret = _badge_changed_monitor_init(uid);
-       if (ret != BADGE_ERROR_NONE) {
+       if (ret == BADGE_ERROR_NONE) {
+               ret = badge_ipc_init_badge(uid);
+               if (ret != BADGE_ERROR_NONE)
+                       return ret;
+       } else {
                /* LCOV_EXCL_START */
                ERR("badge_ipc_monitor_init err : %d", ret);
                _badge_unregister_changed_cb(callback, uid);
index f572efd..d4e954c 100755 (executable)
@@ -27,7 +27,7 @@
 #include "badge_error.h"
 #include "badge_internal.h"
 #include "badge_ipc.h"
-
+#include "badge_setting.h"
 
 #define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
 #define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
@@ -388,7 +388,6 @@ static int _send_sync_badge(GVariant *body, GDBusMessage **reply, char *cmd)
        }
        DBG("_send_sync_badge done !!");
        return BADGE_ERROR_NONE;
-
 }
 
 static int _send_service_register(uid_t uid)
@@ -401,7 +400,6 @@ static int _send_service_register(uid_t uid)
        if (reply)
                g_object_unref(reply);
 
-       badge_changed_cb_call(BADGE_ACTION_SERVICE_READY, NULL, 0, uid);
        DBG("_send_service_register dones");
        return result;
 }
@@ -749,3 +747,123 @@ int badge_ipc_request_get_display(const char *pkgname, unsigned int *is_display,
        DBG("badge_ipc_request_get_display done [result: %d]", result);
        return result;
 }
+
+int badge_ipc_request_update_setting(badge_setting_h setting, uid_t uid)
+{
+       int ret;
+       GDBusMessage *reply = NULL;
+       GVariant *body = NULL;
+
+       ret = _dbus_init();
+       if (ret != BADGE_ERROR_NONE) {
+               ERR("Can't init dbus %d", ret);
+               return ret;
+       }
+
+       body = g_variant_new("(ssii)",
+                            setting->pkgname,
+                            setting->appid,
+                            (int)(setting->allow_to_display),
+                            uid);
+
+       ret = _send_sync_badge(body, &reply, "update_badge_setting");
+       if (ret != BADGE_ERROR_NONE)
+               ERR("Failed badge update setting");
+
+       if (reply)
+               g_object_unref(reply);
+
+       return ret;
+}
+
+int badge_ipc_request_get_setting_by_appid(badge_setting_h *setting, const char *appid, uid_t uid)
+{
+       int ret;
+       GDBusMessage *reply = NULL;
+       GVariant *body = NULL;
+       GVariant *reply_body = NULL;
+       GVariant *setting_body = NULL;
+       badge_setting_h result_setting;
+
+       ret = _dbus_init();
+       if (ret != BADGE_ERROR_NONE) {
+               ERR("Can't init dbus %d", ret);
+               return ret;
+       }
+
+       body = g_variant_new("(si)", appid, uid);
+
+       ret = _send_sync_badge(body, &reply, "get_setting_by_appid");
+       if (ret == BADGE_ERROR_NONE) {
+               reply_body = g_dbus_message_get_body(reply);
+               g_variant_get(reply_body, "(v)", &setting_body);
+
+               result_setting = (struct badge_setting *)malloc(sizeof(struct badge_setting));
+               if (result_setting == NULL) {
+                       ERR("Failed memory allocation.");
+                       g_object_unref(reply);
+                       return BADGE_ERROR_OUT_OF_MEMORY;
+               }
+               badge_ipc_make_setting_from_gvariant(result_setting, setting_body);
+               *setting = result_setting;
+               g_variant_unref(setting_body);
+       }
+
+       if (reply)
+               g_object_ref(reply);
+
+       return ret;
+}
+
+EXPORT_API int badge_ipc_make_setting_from_gvariant(badge_setting_h setting, GVariant *variant)
+{
+       char *pkgname;
+       char *appid;
+       int allow_to_display;
+
+       if (setting == NULL || variant == NULL) {
+               DBG("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       g_variant_get(variant, "(&s&si)", &pkgname, &appid, &allow_to_display);
+
+       setting->pkgname = strdup(pkgname);
+       setting->appid = strdup(appid);
+       setting->allow_to_display = allow_to_display;
+
+       return BADGE_ERROR_NONE;
+}
+
+EXPORT_API GVariant *badge_ipc_make_gvariant_from_setting(badge_setting_h setting)
+{
+       GVariant *body = NULL;
+
+       body = g_variant_new("(ssi)",
+                            setting->pkgname,
+                            setting->appid,
+                            setting->allow_to_display);
+
+       return body;
+}
+
+int badge_ipc_init_badge(uid_t uid)
+{
+       int ret;
+       GDBusMessage *reply = NULL;
+       GVariant *body;
+
+       body = g_variant_new("(i)", uid);
+       if (!body) {
+               ERR("Cannot create gvariant.");
+               return BADGE_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = _send_sync_badge(body, &reply, "init_badge");
+
+       if (reply)
+               g_object_unref(reply);
+
+       DBG("badge_ipc_init_badge done[result:%d]", ret);
+       return ret;
+}
diff --git a/src/badge_setting.c b/src/badge_setting.c
new file mode 100644 (file)
index 0000000..f3d1bdd
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "badge_log.h"
+#include "badge_error.h"
+#include "badge_setting.h"
+#include "badge_ipc.h"
+
+EXPORT_API int badge_setting_get_pkgname(badge_setting_h setting, char **pkgname)
+{
+       if (setting == NULL || pkgname == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       if (setting->pkgname == NULL) {
+               ERR("setting->pkgname is null");
+               return BADGE_ERROR_NOT_EXIST;
+       }
+
+       *pkgname = strdup(setting->pkgname);
+
+       return BADGE_ERROR_NONE;
+}
+
+EXPORT_API int badge_setting_get_appid(badge_setting_h setting, char **appid)
+{
+       if (setting == NULL || appid == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       if (setting->appid == NULL) {
+               ERR("setting->appid is null");
+               return BADGE_ERROR_NOT_EXIST;
+       }
+
+       *appid = strdup(setting->appid);
+
+       return BADGE_ERROR_NONE;
+}
+
+EXPORT_API int badge_setting_set_allow_to_display(badge_setting_h setting, bool value)
+{
+       if (setting == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       setting->allow_to_display = value;
+       return BADGE_ERROR_NONE;
+}
+
+EXPORT_API int badge_setting_get_allow_to_display(badge_setting_h setting, bool *value)
+{
+       if (setting == NULL || value == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       *value = setting->allow_to_display;
+       return BADGE_ERROR_NONE;
+}
+
+EXPORT_API int badge_setting_update_setting_for_uid(badge_setting_h setting, uid_t uid)
+{
+       return badge_ipc_request_update_setting(setting, uid);
+}
+
+EXPORT_API int badge_setting_update_setting(badge_setting_h setting)
+{
+       if (setting == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+       return badge_setting_update_setting_for_uid(setting, getuid());
+}
+
+EXPORT_API int badge_setting_get_setting_by_appid_for_uid(badge_setting_h *setting, const char *appid, uid_t uid)
+{
+       return badge_ipc_request_get_setting_by_appid(setting, appid, uid);
+}
+
+EXPORT_API int badge_setting_get_setting_by_appid(badge_setting_h *setting, const char *appid)
+{
+       if (setting == NULL || appid == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       return badge_setting_get_setting_by_appid_for_uid(setting, appid, getuid());
+}
+
+EXPORT_API int badge_setting_free_setting(badge_setting_h setting)
+{
+       if (setting == NULL) {
+               ERR("Invalid Parameter");
+               return BADGE_ERROR_INVALID_PARAMETER;
+       }
+
+       if (setting->pkgname)
+               free(setting->pkgname);
+       if (setting->appid)
+               free(setting->appid);
+       free(setting);
+       setting = NULL;
+
+       return BADGE_ERROR_NONE;
+}
diff --git a/src/badge_setting_service.c b/src/badge_setting_service.c
new file mode 100644 (file)
index 0000000..46f2a1f
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * 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;
+}
+