--- /dev/null
+Inhong Han <inhong1.han@samsung.com>
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(capi-ui-sticker)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "${PREFIX}")
+SET(VERSION 0.2.56)
+
+ADD_DEFINITIONS("-Werror")
+
+## Include common directory ##
+INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include")
+INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/client")
+INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/provider")
+INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/consumer")
+
+## Dependent packages ##
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ dlog
+ glib-2.0
+ json-glib-1.0
+ libtzplatform-config
+ cynara-client
+ cynara-session
+ capi-appfw-app-common
+ capi-appfw-package-manager
+ sqlite3
+ gio-2.0
+ gio-unix-2.0
+ dbus-1
+)
+
+## API ##
+ADD_SUBDIRECTORY(include)
+
+## Sticker server ##
+ADD_SUBDIRECTORY(server)
+
+## Sticker provider library ##
+ADD_SUBDIRECTORY(provider)
+
+## Sticker consumer library ##
+ADD_SUBDIRECTORY(consumer)
+
+## Sticker parser ##
+ADD_SUBDIRECTORY(sticker-parser)
+
+## config ##
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/capi-ui-sticker.info DESTINATION ${TZ_SYS_RO_SHARE}/parser-plugins)
\ No newline at end of file
--- /dev/null
+Copyright (c) 2019 Samsung Electronics Co., Ltd. All rights reserved.
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+type="category";name="http://tizen.org/category/sticker";path="/etc/package-manager/parserlib/category/libcapi-ui-sticker-parser.so"
+type="metadata";name="http://tizen.org/metadata/sticker";path="/etc/package-manager/parserlib/metadata/libcapi-ui-sticker-parser.so"
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <app_common.h>
+#include <package_manager.h>
+
+#include "sticker_data.h"
+#include "sticker_dbus.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKER_DATA"
+
+static char* _make_absolute_path(const char *relative_path)
+{
+ int ret = STICKER_ERROR_NONE;
+ char *app_id = NULL;
+ package_info_h package_info = NULL;
+ char *app_path = NULL;
+ char *file_path = NULL;
+
+ ret = app_get_id(&app_id);
+ if (ret != APP_ERROR_NONE) {
+ LOGE("Failed to get app_id : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ ret = package_info_create(app_id, &package_info);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ ret = package_info_get_root_path(package_info, &app_path);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ int path_len = strlen(app_path) + strlen(relative_path) + 2;
+ file_path = (char *)calloc(path_len, sizeof(char));
+ if (!file_path) {
+ LOGE("failed to alloc memory");
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if(relative_path[0] == '/')
+ snprintf(file_path, path_len, "%s%s",app_path, relative_path);
+ else
+ snprintf(file_path, path_len, "%s%s%s",app_path, "/", relative_path);
+
+ if (access(file_path, F_OK) != 0) {
+ LOGE("%s does not exist", file_path);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ free(file_path);
+ }
+
+cleanup:
+ if (app_id)
+ free(app_id);
+
+ if (package_info)
+ package_info_destroy(package_info);
+
+ if (app_path)
+ free(app_path);
+
+ if (ret == STICKER_ERROR_NONE)
+ return file_path;
+ else
+ return NULL;
+}
+
+EXPORT_API int sticker_data_create(sticker_data_h *data_handle)
+{
+ if (!data_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ sticker_data_h data_struct = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+
+ if (!data_struct)
+ return STICKER_ERROR_OUT_OF_MEMORY;
+
+ char *app_id = NULL;
+ int ret = app_get_id(&app_id);
+ if (ret != APP_ERROR_NONE) {
+ LOGE("Failed to get app_id : %d", ret);
+ free(data_struct);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ data_struct->app_id = strdup(app_id);
+ *data_handle = data_struct;
+
+cleanup:
+ if (app_id)
+ free(app_id);
+
+ return ret;
+}
+
+EXPORT_API int sticker_data_destroy(sticker_data_h data_handle)
+{
+ if (!data_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (data_handle->app_id) {
+ free(data_handle->app_id);
+ data_handle->app_id = NULL;
+ }
+
+ if (data_handle->uri) {
+ free(data_handle->uri);
+ data_handle->uri = NULL;
+ }
+
+ if (data_handle->thumbnail) {
+ free(data_handle->thumbnail);
+ data_handle->thumbnail = NULL;
+ }
+
+ if (data_handle->keyword) {
+ g_list_free_full(data_handle->keyword, free);
+ data_handle->keyword = NULL;
+ }
+
+ if (data_handle->group) {
+ free(data_handle->group);
+ data_handle->group = NULL;
+ }
+
+ if (data_handle->description) {
+ free(data_handle->description);
+ data_handle->description = NULL;
+ }
+
+ if (data_handle->date) {
+ free(data_handle->date);
+ data_handle->date = NULL;
+ }
+
+ free(data_handle);
+ data_handle = NULL;
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_clone(sticker_data_h origin_handle, sticker_data_h *target_handle)
+{
+ sticker_data_h handle;
+
+ if (!origin_handle || !target_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ sticker_data_create(&handle);
+ if (!handle)
+ return STICKER_ERROR_OUT_OF_MEMORY;
+
+ handle->sticker_info_id = origin_handle->sticker_info_id;
+
+ if (origin_handle->app_id)
+ handle->app_id = strdup(origin_handle->app_id);
+
+ handle->type = origin_handle->type;
+
+ if (origin_handle->uri)
+ handle->uri = strdup(origin_handle->uri);
+
+ if (origin_handle->thumbnail)
+ handle->thumbnail = strdup(origin_handle->thumbnail);
+
+ if (origin_handle->keyword)
+ handle->keyword = g_list_copy_deep(origin_handle->keyword, (GCopyFunc) g_strdup, NULL);
+
+ if (origin_handle->group)
+ handle->group = strdup(origin_handle->group);
+
+ if (origin_handle->description)
+ handle->description = strdup(origin_handle->description);
+
+ if (origin_handle->date)
+ handle->date = strdup(origin_handle->date);
+
+ *target_handle = handle;
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_get_app_id(sticker_data_h data_handle, char **app_id)
+{
+ if (!data_handle || !app_id)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->app_id)
+ return STICKER_ERROR_OPERATION_FAILED;
+
+ *app_id = strdup(data_handle->app_id);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_set_uri(sticker_data_h data_handle, sticker_data_uri_type_e type, const char *uri)
+{
+ char *file_path = NULL;
+
+ if (!data_handle || !type || !uri)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (type == STICKER_DATA_URI_LOCAL_PATH) {
+ if (access(uri, F_OK) != 0) {
+ file_path = _make_absolute_path(uri);
+ if (file_path == NULL) {
+ return STICKER_ERROR_INVALID_PARAMETER;
+ }
+ } else
+ file_path = strdup(uri);
+ }
+
+ if (data_handle->uri)
+ free(data_handle->uri);
+
+ data_handle->type = type;
+ if (type == STICKER_DATA_URI_LOCAL_PATH)
+ data_handle->uri = file_path;
+ else
+ data_handle->uri = strdup(uri);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_get_uri(sticker_data_h data_handle, sticker_data_uri_type_e *type, char **uri)
+{
+ if (!data_handle || !type || !uri)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->type || !data_handle->uri)
+ return STICKER_ERROR_OPERATION_FAILED;
+
+ *type = data_handle->type;
+ *uri = strdup(data_handle->uri);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_foreach_keyword(sticker_data_h data_handle, sticker_data_keyword_foreach_cb callback, void *user_data)
+{
+ if (!data_handle || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->keyword)
+ return STICKER_ERROR_OPERATION_FAILED;
+
+ GList *list = NULL;
+ for(list = g_list_first(data_handle->keyword); list != NULL; list=list->next) {
+ callback(list->data, user_data);
+ }
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_add_keyword(sticker_data_h data_handle, const char *keyword)
+{
+ GList *node;
+
+ if (!data_handle || !keyword)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ node = g_list_find_custom(data_handle->keyword, keyword, (GCompareFunc) strcmp);
+
+ if (node) {
+ LOGE("keyword already exists");
+ return STICKER_ERROR_INVALID_PARAMETER;
+ } else {
+ data_handle->keyword = g_list_append(data_handle->keyword, strdup(keyword));
+ }
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_remove_keyword(sticker_data_h data_handle, const char *keyword)
+{
+ GList *node;
+
+ if (!data_handle || !keyword)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ node = g_list_find_custom(data_handle->keyword, keyword, (GCompareFunc) strcmp);
+
+ if (node) {
+ data_handle->keyword = g_list_delete_link(data_handle->keyword, node);
+ } else {
+ LOGE("keyword does not exist");
+ return STICKER_ERROR_INVALID_PARAMETER;
+ }
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_set_group_name(sticker_data_h data_handle, const char *group)
+{
+ if (!data_handle || !group)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (data_handle->group)
+ free(data_handle->group);
+
+ data_handle->group = strdup(group);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_get_group_name(sticker_data_h data_handle, char **group)
+{
+ if (!data_handle || !group)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->group)
+ return STICKER_ERROR_OPERATION_FAILED;
+
+ *group = strdup(data_handle->group);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_set_thumbnail(sticker_data_h data_handle, const char *thumbnail)
+{
+ char *file_path = NULL;
+
+ if (!data_handle || !thumbnail)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (access(thumbnail, F_OK) != 0) {
+ file_path = _make_absolute_path(thumbnail);
+ if (file_path == NULL)
+ return STICKER_ERROR_INVALID_PARAMETER;
+ } else
+ file_path = strdup(thumbnail);
+
+ if (data_handle->thumbnail)
+ free(data_handle->thumbnail);
+
+ data_handle->thumbnail = file_path;
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_get_thumbnail(sticker_data_h data_handle, char **thumbnail)
+{
+ if (!data_handle || !thumbnail)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->thumbnail)
+ *thumbnail = strdup("");
+ else
+ *thumbnail = strdup(data_handle->thumbnail);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_set_description(sticker_data_h data_handle, const char *description)
+{
+ if (!data_handle || !description)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (data_handle->description)
+ free(data_handle->description);
+
+ data_handle->description = strdup(description);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_get_description(sticker_data_h data_handle, char **description)
+{
+ if (!data_handle || !description)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->description)
+ *description = strdup("");
+ else
+ *description = strdup(data_handle->description);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_data_get_date(sticker_data_h data_handle, char **date)
+{
+ if (!data_handle || !date)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (!data_handle->date)
+ return STICKER_ERROR_OPERATION_FAILED;
+
+ *date = strdup(data_handle->date);
+
+ return STICKER_ERROR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_DATA_MAIN_H__
+#define __TIZEN_UIX_STICKER_DATA_MAIN_H__
+
+#include <glib.h>
+#include "sticker_data.h"
+
+/**
+ * @file sticker_data_main.h
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct sticker_data_s{
+ int sticker_info_id;
+ char *app_id;
+ sticker_data_uri_type_e type;
+ char *uri;
+ char *thumbnail;
+ GList *keyword;
+ char *group;
+ char *description;
+ char *date;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+ */
+
+#endif /* __TIZEN_UIX_STICKER_DATA_MAIN_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <dlog.h>
+
+#include "sticker_dbus.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKER_DBUS"
+
+static int is_server_started = 0;
+
+static void _server_appeared_cb(GDBusConnection *connection, const gchar *name, const gchar *name_owner, gpointer user_data)
+{
+ LOGD("name : %s, name_owner : %s", name, name_owner);
+}
+
+static void _server_vanished_cb(GDBusConnection *connection, const gchar *name, gpointer user_data)
+{
+ LOGD("name : %s", name);
+}
+
+static int _dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id)
+{
+ GError *error = NULL;
+
+ if (*gdbus_connection == NULL) {
+ GDBusConnection *conn = NULL;
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (conn == NULL) {
+ if (error != NULL) {
+ LOGE("g_bus_get_sync error message = %s", error->message);
+ g_error_free(error);
+ }
+ return STICKER_CLIENT_ERROR_IO_ERROR;
+ }
+ *gdbus_connection = conn;
+ }
+
+ LOGD("Connected bus name : %s", g_dbus_connection_get_unique_name(*gdbus_connection));
+ if (*server_watcher_id == 0) {
+ *server_watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
+ STICKER_DBUS_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ _server_appeared_cb,
+ _server_vanished_cb,
+ NULL, NULL);
+ }
+
+ LOGD("server_watcher_id : %d", *server_watcher_id);
+ if (*server_watcher_id == 0) {
+ LOGE("Failed to get identifier");
+ return STICKER_CLIENT_ERROR_IO_ERROR;
+ }
+
+ return STICKER_CLIENT_ERROR_NONE;
+}
+
+static void _get_sticker_info_from_gvariant(GVariant *body, sticker_data_h sticker_data)
+{
+ STICKER_DAT_TYPE key;
+ GVariant *value = NULL;
+ GVariantIter *info_iter = NULL;
+ GVariantIter *keyword_iter = NULL;
+ char *keyword = NULL;
+
+ g_variant_get(body, "(a{iv}a(s))", &info_iter, &keyword_iter);
+
+ if (!info_iter || !keyword_iter) {
+ LOGD("failed to get iter");
+ return;
+ }
+
+ while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
+ switch(key) {
+ case STICKER_DATA_TYPE_APP_ID:
+ sticker_data->app_id = g_variant_dup_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_URI_TYPE:
+ sticker_data->type = g_variant_get_int32(value);
+ break;
+ case STICKER_DATA_TYPE_URI:
+ sticker_data->uri = g_variant_dup_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_THUMBNAIL:
+ sticker_data->thumbnail = g_variant_dup_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_DESCRIPTION:
+ sticker_data->description = g_variant_dup_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_GROUP:
+ sticker_data->group = g_variant_dup_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_DATE:
+ sticker_data->date = g_variant_dup_string(value, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
+ sticker_data->keyword = g_list_append(sticker_data->keyword, strdup((const char *)keyword));
+ }
+
+ if (value)
+ g_variant_unref(value);
+
+ g_variant_iter_free(info_iter);
+ g_variant_iter_free(keyword_iter);
+}
+
+static void _free_sticker_data(sticker_data_h sticker_data)
+{
+ if (sticker_data->app_id) {
+ free(sticker_data->app_id);
+ sticker_data->app_id = NULL;
+ }
+
+ if (sticker_data->uri) {
+ free(sticker_data->uri);
+ sticker_data->uri = NULL;
+ }
+
+ if (sticker_data->thumbnail) {
+ free(sticker_data->thumbnail);
+ sticker_data->thumbnail = NULL;
+ }
+
+ if (sticker_data->keyword) {
+ g_list_free_full(sticker_data->keyword, free);
+ sticker_data->keyword = NULL;
+ }
+
+ if (sticker_data->group) {
+ free(sticker_data->group);
+ sticker_data->group = NULL;
+ }
+
+ if (sticker_data->description) {
+ free(sticker_data->description);
+ sticker_data->description = NULL;
+ }
+
+ if (sticker_data->date) {
+ free(sticker_data->date);
+ sticker_data->date = NULL;
+ }
+
+ free(sticker_data);
+ sticker_data = NULL;
+}
+
+static void _call_insert_finished_cb(sticker_provider_h provider_handle, GVariant *body)
+{
+ int ret;
+ g_variant_get(body, "(i)", &ret);
+
+ if (ret == 0) {
+ provider_handle->insert_finished_cb(STICKER_ERROR_NONE, provider_handle->insert_finished_cb_user_data);
+ } else {
+ provider_handle->insert_finished_cb(STICKER_ERROR_OPERATION_FAILED, provider_handle->insert_finished_cb_user_data);
+ }
+}
+
+static void _handle_sticker_consumer_cb(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
+ sticker_consumer_h consumer_handle = (sticker_consumer_h)user_data;
+
+ if (consumer_handle == NULL) {
+ LOGE("consumer handle is not available");
+ return;
+ }
+
+ if (parameters == NULL) {
+ LOGE("failed to get sticker info");
+ return;
+ }
+
+ #if 0 // Receive the sticker information by asynchronous communication.
+ if (g_strcmp0(signal_name, "send_group_list") == 0) {
+ if (consumer_handle->group_foreach_cb != NULL)
+ _call_sticker_list_cb(consumer_handle, parameters, signal_name);
+ return;
+ } else if (g_strcmp0(signal_name, "send_keyword_list") == 0) {
+ if (consumer_handle->keyword_foreach_cb != NULL)
+ _call_sticker_list_cb(consumer_handle, parameters, signal_name);
+ return;
+ }
+
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+
+ if (!sticker_data) {
+ LOGE("failed to allocate memory");
+ return;
+ }
+
+ _get_sticker_info_from_gvariant(parameters, sticker_data);
+
+ if (g_strcmp0(signal_name, "send_all_sticker_info") == 0) {
+ if (consumer_handle->data_foreach_cb != NULL)
+ consumer_handle->data_foreach_cb(sticker_data, consumer_handle->data_foreach_cb_user_data);
+ else
+ LOGW("No registered callback function");
+ } else if (g_strcmp0(signal_name, "send_sticker_info_by_keyword") == 0) {
+ if (consumer_handle->data_foreach_by_keyword_cb != NULL)
+ consumer_handle->data_foreach_by_keyword_cb(sticker_data, consumer_handle->data_foreach_by_keyword_cb_user_data);
+ else
+ LOGW("No registered callback function");
+ } else if (g_strcmp0(signal_name, "send_sticker_info_by_goup") == 0) {
+ if (consumer_handle->data_foreach_by_group_cb != NULL)
+ consumer_handle->data_foreach_by_group_cb(sticker_data, consumer_handle->data_foreach_by_group_cb_user_data);
+ else
+ LOGW("No registered callback function");
+ } else if (g_strcmp0(signal_name, "send_sticker_info_by_type") == 0) {
+ if (consumer_handle->data_foreach_by_type_cb != NULL)
+ consumer_handle->data_foreach_by_type_cb(sticker_data, consumer_handle->data_foreach_by_type_cb_user_data);
+ else
+ LOGW("No registered callback function");
+ }
+
+ _free_sticker_data(sticker_data);
+ #endif
+}
+
+static void _handle_sticker_provider_cb(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ LOGD("own_name : %s, signal_name : %s", g_dbus_connection_get_unique_name(connection), signal_name);
+ sticker_provider_h provider_handle = (sticker_provider_h)user_data;
+
+ if (provider_handle == NULL) {
+ LOGE("provider handle is not available");
+ return;
+ }
+
+ if (parameters == NULL) {
+ LOGE("failed to get sticker info");
+ return;
+ }
+
+ if (g_strcmp0(signal_name, "send_insert_result") == 0) {
+ if (provider_handle->insert_finished_cb != NULL)
+ _call_insert_finished_cb(provider_handle, parameters);
+ }
+
+ #if 0 // Receive the sticker information by asynchronous communication.
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+
+ if (!sticker_data) {
+ LOGE("failed to allocate memory");
+ return;
+ }
+
+ _get_sticker_info_from_gvariant(parameters, sticker_data);
+
+ if (g_strcmp0(signal_name, "send_sticker_info_by_appid") == 0) {
+ if (provider_handle->data_foreach_cb != NULL)
+ provider_handle->data_foreach_cb(sticker_data, provider_handle->data_foreach_cb_user_data);
+ else
+ LOGW("No registered callback function");
+ }
+
+ _free_sticker_data(sticker_data);
+ #endif
+}
+
+static int _dbus_signal_init(GDBusConnection *gdbus_connection, int *monitor_id, CLIENT_LIB lib, void *data)
+{
+ int ret = STICKER_CLIENT_ERROR_NONE;
+ if (*monitor_id == 0) {
+ int id = 0;
+ if (lib == STICKER_CLIENT_LIB_CONSUMER)
+ id = g_dbus_connection_signal_subscribe(gdbus_connection,
+ STICKER_DBUS_NAME,
+ STICKER_CONSUMER_INTERFACE_NAME,
+ NULL,
+ STICKER_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _handle_sticker_consumer_cb,
+ data,
+ NULL);
+ else if (lib == STICKER_CLIENT_LIB_PROVIDER)
+ id = g_dbus_connection_signal_subscribe(gdbus_connection,
+ STICKER_DBUS_NAME,
+ STICKER_PROVIDER_INTERFACE_NAME,
+ NULL,
+ STICKER_OBJECT_PATH,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _handle_sticker_provider_cb,
+ data,
+ NULL);
+ LOGD("id : %d", id);
+ if (id == 0) {
+ ret = STICKER_CLIENT_ERROR_IO_ERROR;
+ LOGE("g_dbus_connection_signal_subscribe() failed");
+ } else {
+ *monitor_id = id;
+ }
+ }
+
+ return ret;
+}
+
+static GDBusMessage *_get_gbus_message(GVariant *body, const char *cmd)
+{
+ GDBusMessage *message = NULL;
+ message = g_dbus_message_new_method_call(
+ STICKER_DBUS_NAME,
+ STICKER_OBJECT_PATH,
+ STICKER_INTERFACE_NAME,
+ cmd);
+
+ if (!message) {
+ LOGE("Failed to create a new gdbus message");
+ if (body)
+ g_variant_unref(body);
+ return NULL;
+ }
+
+ if (body != NULL)
+ g_dbus_message_set_body(message, body);
+
+ return message;
+}
+
+static int _send_gdbus_sync_message(GDBusConnection *gdbus_connection, GDBusMessage *msg, GDBusMessage **reply, const char *cmd)
+{
+ int ret = STICKER_CLIENT_ERROR_NONE;
+ GError *err = NULL;
+
+ *reply = g_dbus_connection_send_message_with_reply_sync(
+ gdbus_connection,
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ &err);
+
+ if (!*reply) {
+ ret = STICKER_CLIENT_ERROR_SERVICE_NOT_READY;
+ if (err != NULL) {
+ LOGE("Error occurred when sending message(%s) : %s", cmd, err->message);
+ if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
+ ret = STICKER_CLIENT_ERROR_PERMISSION_DENIED;
+ g_error_free(err);
+ }
+ return ret;
+ }
+
+ if (g_dbus_message_to_gerror(*reply, &err)) {
+ LOGE("error message = %s, code = %d", err->message, err->code);
+ if (err->code == G_DBUS_ERROR_ACCESS_DENIED)
+ ret = STICKER_CLIENT_ERROR_PERMISSION_DENIED;
+ else
+ ret = err->code;
+ g_error_free(err);
+ return ret;
+ }
+
+ LOGD("Send a message to server(cmd : %s)", cmd);
+ return STICKER_CLIENT_ERROR_NONE;
+}
+
+static int _send_sync_message(GDBusConnection *gdbus_connection, GVariant *body, GDBusMessage **reply, char *cmd)
+{
+ int ret = STICKER_CLIENT_ERROR_NONE;
+ GDBusMessage *msg = NULL;
+
+ msg = _get_gbus_message(body, cmd);
+ if (msg == NULL)
+ return STICKER_CLIENT_ERROR_IO_ERROR;
+
+ ret = _send_gdbus_sync_message(gdbus_connection, msg, reply, cmd);
+
+ if (msg)
+ g_object_unref(msg);
+
+ return ret;
+}
+
+static void _gdbus_reply_message_async_cb(GDBusConnection *connection, GAsyncResult *res, gpointer user_data)
+{
+ GDBusMessage *reply = NULL;
+ GError *err = NULL;
+
+ reply = g_dbus_connection_send_message_with_reply_finish(connection, res, &err);
+
+ if (reply) {
+ if (g_dbus_message_to_gerror(reply, &err)) {
+ LOGE("error message = %s, code = %d", err->message, err->code);
+ g_error_free(err);
+ return;
+ }
+ } else {
+ LOGE("There is no reply");
+ return;
+ }
+
+ if (reply)
+ g_object_unref(reply);
+
+ LOGD("Reply message was received");
+ return;
+}
+
+static int _send_async_message(GDBusConnection *gdbus_connection, GVariant *body, char *cmd)
+{
+ int ret = STICKER_CLIENT_ERROR_NONE;
+ GDBusMessage *msg = NULL;
+
+ msg = _get_gbus_message(body, cmd);
+ if (msg == NULL)
+ return STICKER_CLIENT_ERROR_IO_ERROR;
+
+ g_dbus_connection_send_message_with_reply(
+ gdbus_connection,
+ msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ (GAsyncReadyCallback)_gdbus_reply_message_async_cb,
+ NULL);
+
+ if (msg)
+ g_object_unref(msg);
+
+ return ret;
+}
+
+static int _monitor_register(GDBusConnection *gdbus_connection)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+
+ ret = _send_sync_message(gdbus_connection, g_variant_new("()"), &reply, "sticker_service_register");
+ if (reply)
+ g_object_unref(reply);
+
+ if (ret != STICKER_CLIENT_ERROR_NONE) {
+ LOGE("_send_sync_message() failed : %d", ret);
+ return ret;
+ }
+
+ is_server_started = 1;
+ return ret;
+}
+
+static void _on_name_appeared(GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ if (is_server_started == 0)
+ _monitor_register(connection);
+}
+
+static void _on_name_vanished(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ is_server_started = 0;
+}
+
+int sticker_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
+ int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data)
+{
+ int ret;
+
+ ret = _dbus_init(gdbus_connection, server_watcher_id);
+ if (ret != STICKER_CLIENT_ERROR_NONE) {
+ LOGE("_dbus_init() failed : %d", ret);
+ return ret;
+ }
+
+ ret = _dbus_signal_init(*gdbus_connection, monitor_id, lib, data);
+ if (ret != STICKER_CLIENT_ERROR_NONE) {
+ LOGE("_dbus_signal_init() failed : %d", ret);
+ return ret;
+ }
+
+ ret = _monitor_register(*gdbus_connection);
+ if (ret != STICKER_CLIENT_ERROR_NONE) {
+ LOGE("_monitor_register() failed : %d", ret);
+ return ret;
+ }
+
+ if (*server_monitor_id == 0) {
+ *server_monitor_id = g_bus_watch_name_on_connection(
+ *gdbus_connection,
+ STICKER_DBUS_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ _on_name_appeared,
+ _on_name_vanished,
+ NULL,
+ NULL);
+ if (*server_monitor_id == 0) {
+ g_dbus_connection_signal_unsubscribe(*gdbus_connection, *monitor_id);
+ *monitor_id = 0;
+ LOGE("Failed to get identifier");
+ return STICKER_CLIENT_ERROR_IO_ERROR;
+ }
+ }
+
+ return STICKER_CLIENT_ERROR_NONE;
+}
+
+int sticker_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id)
+{
+ if (*server_monitor_id) {
+ g_bus_unwatch_name(*server_monitor_id);
+ *server_monitor_id = 0;
+ }
+
+ if (*monitor_id) {
+ g_dbus_connection_signal_unsubscribe(gdbus_connection, *monitor_id);
+ *monitor_id = 0;
+ }
+
+ return STICKER_CLIENT_ERROR_NONE;
+}
+
+static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
+{
+ if (!keyword) {
+ LOGE("keyword doesn't exist");
+ return;
+ }
+
+ g_variant_builder_add(keyword_builder, "(s)", strdup((const char *)keyword));
+}
+
+int sticker_dbus_insert_sticker_info(GDBusConnection *gdbus_connection, sticker_data_h sticker_data)
+{
+ int ret;
+ int ret_id = -1;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+ GVariantBuilder *info_builder;
+ GVariantBuilder *keyword_builder;
+
+ if (!sticker_data->app_id || (sticker_data->type < 1) || !sticker_data->uri || !sticker_data->group || !sticker_data->keyword)
+ return STICKER_CLIENT_ERROR_INVALID_PARAMETER;
+
+ info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_data->app_id));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_data->type));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_data->uri));
+ if (sticker_data->thumbnail)
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_data->thumbnail));
+ if (sticker_data->description)
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_data->description));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_data->group));
+
+ keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+ g_list_foreach(sticker_data->keyword, (GFunc) _set_keyword_builder, keyword_builder);
+
+ body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
+
+ g_variant_builder_unref(info_builder);
+ g_variant_builder_unref(keyword_builder);
+
+ ret = _send_sync_message(gdbus_connection, body, &reply, "insert_sticker_info");
+ if (ret != STICKER_CLIENT_ERROR_NONE) {
+ LOGW("Failed to save sticker info");
+ return ret;
+ }
+
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(i)", &ret_id);
+ sticker_data->sticker_info_id = ret_id;
+
+ LOGD("ret_id : %d", ret_id);
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_insert_sticker_info_by_json(GDBusConnection *gdbus_connection, const char *app_id, const char *json_path)
+{
+ int ret;
+ GVariant *body = NULL;
+
+ body = g_variant_new("(ss)", app_id, json_path);
+ ret = _send_async_message(gdbus_connection, body, "update_sticker_info_by_json");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("failed to send json path");
+
+ if (body)
+ g_variant_unref(body);
+
+ return ret;
+}
+
+int sticker_dbus_delete_sticker_info(GDBusConnection *gdbus_connection, int record_id)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+
+ body = g_variant_new("(i)", record_id);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "delete_sticker_info");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("failed to delete sticker info");
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_update_sticker_info(GDBusConnection *gdbus_connection, sticker_data_h sticker_data)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+ sticker_data_h origin_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+
+ if (!origin_data) {
+ LOGE("failed to allocate memory");
+ return STICKER_CLIENT_ERROR_OUT_OF_MEMORY;
+ }
+
+ body = g_variant_new("(i)", sticker_data->sticker_info_id);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info");
+
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ _get_sticker_info_from_gvariant(reply_body, origin_data);
+ } else {
+ LOGW("failed to get sticker info");
+ free(origin_data);
+ if (reply)
+ g_object_unref(reply);
+ if (body)
+ g_variant_unref(body);
+ return ret;
+ }
+
+ if (sticker_data->type != 0 && sticker_data->type != origin_data->type) {
+ LOGD("origin_type : %d, new_type : %d", origin_data->type, sticker_data->type);
+ g_variant_unref(body);
+ body = g_variant_new("(ii)", sticker_data->sticker_info_id, sticker_data->type);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_type");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("falied to update sticker type");
+ }
+
+ if (sticker_data->uri && strcmp(sticker_data->uri, origin_data->uri) != 0) {
+ LOGD("origin_uri : %s, new_uri : %s", origin_data->uri, sticker_data->uri);
+ g_variant_unref(body);
+ body = g_variant_new("(isis)", sticker_data->sticker_info_id, sticker_data->app_id, sticker_data->type, sticker_data->uri);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_uri");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("falied to update sticker uri");
+ }
+
+ if (sticker_data->thumbnail && strcmp(sticker_data->thumbnail, origin_data->thumbnail) != 0) {
+ LOGD("origin_thumbnail : %s, new_thumbnail : %s", origin_data->thumbnail, sticker_data->thumbnail);
+ g_variant_unref(body);
+ body = g_variant_new("(is)", sticker_data->sticker_info_id, sticker_data->thumbnail);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_thumbnail");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("falied to update sticker thumbnail");
+ }
+
+ if (sticker_data->description && strcmp(sticker_data->description, origin_data->description) != 0) {
+ LOGD("origin_description : %s, new_description : %s", origin_data->description, sticker_data->description);
+ g_variant_unref(body);
+ body = g_variant_new("(is)", sticker_data->sticker_info_id, sticker_data->description);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_description");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("falied to update sticker description");
+ }
+
+ if (sticker_data->group && strcmp(sticker_data->group, origin_data->group) != 0) {
+ LOGD("origin_group : %s, new_group : %s", origin_data->group, sticker_data->group);
+ g_variant_unref(body);
+ body = g_variant_new("(is)", sticker_data->sticker_info_id, sticker_data->group);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_group");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("falied to update sticker group");
+ }
+
+ if (sticker_data->keyword) {
+ GVariantBuilder *keyword_builder;
+ g_variant_unref(body);
+ keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+ g_list_foreach(sticker_data->keyword, (GFunc) _set_keyword_builder, keyword_builder);
+ body = g_variant_new("(ia(s))", sticker_data->sticker_info_id, keyword_builder);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "update_sticker_keyword");
+ if (ret != STICKER_CLIENT_ERROR_NONE)
+ LOGE("falied to update sticker keyword");
+ }
+
+ _free_sticker_data(origin_data);
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_sticker_info_by_record_id(GDBusConnection *gdbus_connection, sticker_data_h sticker_data, int record_id)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(i)", record_id);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info");
+
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ sticker_data->sticker_info_id = record_id;
+ _get_sticker_info_from_gvariant(reply_body, sticker_data);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_group_list(GDBusConnection *gdbus_connection, GList **group_list)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariantIter *iter = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+ char *group = NULL;
+
+ if (group_list == NULL) {
+ LOGE("group_list is invalid");
+ return STICKER_CLIENT_ERROR_INVALID_PARAMETER;
+ }
+
+ body = g_variant_new("()");
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_group_list");
+
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(s))", &iter);
+
+ if (!iter) {
+ LOGD("falied to get iter");
+ return STICKER_CLIENT_ERROR_OPERATION_FAILED;
+ }
+
+ while (g_variant_iter_loop (iter, "(s)", &group)) {
+ *group_list = g_list_append(*group_list, strdup((const char *)group));
+ }
+
+ g_variant_iter_free(iter);
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_keyword_list(GDBusConnection *gdbus_connection, GList **keyword_list)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariantIter *iter = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+ char *keyword = NULL;
+
+ if (keyword_list == NULL) {
+ LOGE("keyword_list is invalid");
+ return STICKER_CLIENT_ERROR_INVALID_PARAMETER;
+ }
+
+ body = g_variant_new("()");
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_keyword_list");
+
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(s))", &iter);
+
+ if (!iter) {
+ LOGD("falied to get iter");
+ return STICKER_CLIENT_ERROR_OPERATION_FAILED;
+ }
+
+ while (g_variant_iter_loop (iter, "(s)", &keyword)) {
+ *keyword_list = g_list_append(*keyword_list, strdup((const char *)keyword));
+ }
+
+ g_variant_iter_free(iter);
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_sticker_count(GDBusConnection *gdbus_connection, const char *app_id, int *count)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(s)", app_id);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_count");
+
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(i)", count);
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_all_sticker_info(GDBusConnection *gdbus_connection, int offset, int count, GVariantIter **id_iter)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(ii)", offset, count);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_all_sticker_info");
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(i))", &(*id_iter));
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_sticker_info_by_appid(GDBusConnection *gdbus_connection, const char *app_id, int offset, int count, GVariantIter **id_iter)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(sii)", app_id, offset, count);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_appid");
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(i))", &(*id_iter));
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_sticker_info_by_type(GDBusConnection *gdbus_connection, sticker_data_uri_type_e type, int offset, int count, GVariantIter **id_iter)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(iii)", (int)type, offset, count);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_type");
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(i))", &(*id_iter));
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_sticker_info_by_group(GDBusConnection *gdbus_connection, const char *group, int offset, int count, GVariantIter **id_iter)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(sii)", group, offset, count);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_group");
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(i))", &(*id_iter));
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
+
+int sticker_dbus_get_sticker_info_by_keyword(GDBusConnection *gdbus_connection, const char *keyword, int offset, int count, GVariantIter **id_iter)
+{
+ int ret;
+ GDBusMessage *reply = NULL;
+ GVariant *body = NULL;
+ GVariant *reply_body = NULL;
+
+ body = g_variant_new("(sii)", keyword, offset, count);
+ ret = _send_sync_message(gdbus_connection, body, &reply, "get_sticker_info_by_keyword");
+ if (ret == STICKER_CLIENT_ERROR_NONE) {
+ reply_body = g_dbus_message_get_body(reply);
+ g_variant_get(reply_body, "(a(i))", &(*id_iter));
+ }
+
+ if (body)
+ g_variant_unref(body);
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+
+ if (reply)
+ g_object_unref(reply);
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_DBUS_H__
+#define __TIZEN_UIX_STICKER_DBUS_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <dbus/dbus.h>
+#include "sticker_defs.h"
+#include "sticker_data.h"
+#include "sticker_data_main.h"
+#include "sticker_provider_main.h"
+#include "sticker_consumer_main.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum sticker_client_error {
+ STICKER_CLIENT_ERROR_NONE,
+ STICKER_CLIENT_ERROR_INVALID_PARAMETER,
+ STICKER_CLIENT_ERROR_PERMISSION_DENIED,
+ STICKER_CLIENT_ERROR_OUT_OF_MEMORY,
+ STICKER_CLIENT_ERROR_SERVICE_NOT_READY,
+ STICKER_CLIENT_ERROR_OPERATION_FAILED,
+ STICKER_CLIENT_ERROR_IO_ERROR,
+};
+
+int sticker_dbus_init(GDBusConnection **gdbus_connection, guint *server_watcher_id,
+ int *monitor_id, int *server_monitor_id, CLIENT_LIB lib, void *data);
+int sticker_dbus_shutdown(GDBusConnection *gdbus_connection, int *server_monitor_id, int *monitor_id);
+int sticker_dbus_insert_sticker_info(GDBusConnection *gdbus_connection, sticker_data_h sticker_data);
+int sticker_dbus_insert_sticker_info_by_json(GDBusConnection *gdbus_connection, const char *app_id, const char *json_path);
+int sticker_dbus_delete_sticker_info(GDBusConnection *gdbus_connection, int record_id);
+int sticker_dbus_update_sticker_info(GDBusConnection *gdbus_connection, sticker_data_h sticker_data);
+int sticker_dbus_get_sticker_info_by_record_id(GDBusConnection *gdbus_connection, sticker_data_h sticker_data, int record_id);
+int sticker_dbus_get_group_list(GDBusConnection *gdbus_connection, GList **group_list);
+int sticker_dbus_get_keyword_list(GDBusConnection *gdbus_connection, GList **keyword_list);
+int sticker_dbus_get_sticker_count(GDBusConnection *gdbus_connection, const char *app_id, int *count);
+int sticker_dbus_get_all_sticker_info(GDBusConnection *gdbus_connection, int offset, int count, GVariantIter **id_iter);
+int sticker_dbus_get_sticker_info_by_appid(GDBusConnection *gdbus_connection, const char *app_id, int offset, int count, GVariantIter **id_iter);
+int sticker_dbus_get_sticker_info_by_type(GDBusConnection *gdbus_connection, sticker_data_uri_type_e type, int offset, int count, GVariantIter **id_iter);
+int sticker_dbus_get_sticker_info_by_group(GDBusConnection *gdbus_connection, const char *group, int offset, int count, GVariantIter **id_iter);
+int sticker_dbus_get_sticker_info_by_keyword(GDBusConnection *gdbus_connection, const char *keyword, int offset, int count, GVariantIter **id_iter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_DBUS_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_DEFS_H__
+#define __TIZEN_UIX_STICKER_DEFS_H__
+
+#include <tzplatform_config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAPI __attribute__((visibility("hidden")))
+
+#define DBUS_NAME "org.freedesktop.DBus"
+#define DBUS_OBJECT_PATH "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_NAME "org.freedesktop.DBus"
+
+#define STICKER_DBUS_NAME "org.tizen.sticker.server"
+#define STICKER_OBJECT_PATH "/org/tizen/sticker/server"
+#define STICKER_INTERFACE_NAME "org.tizen.sticker_service"
+#define STICKER_PROVIDER_INTERFACE_NAME "org.tizen.sticker_provider"
+#define STICKER_CONSUMER_INTERFACE_NAME "org.tizen.sticker_consumer"
+
+#define STICKER_PRIVILEGE_MEDIASTORAGE "http://tizen.org/privilege/mediastorage"
+
+typedef enum {
+ STICKER_CLIENT_LIB_NONE,
+ STICKER_CLIENT_LIB_CONSUMER,
+ STICKER_CLIENT_LIB_PROVIDER,
+} CLIENT_LIB;
+
+typedef enum {
+ STICKER_DATA_TYPE_INFO_ID = 1,
+ STICKER_DATA_TYPE_APP_ID,
+ STICKER_DATA_TYPE_URI_TYPE,
+ STICKER_DATA_TYPE_URI,
+ STICKER_DATA_TYPE_THUMBNAIL,
+ STICKER_DATA_TYPE_DESCRIPTION,
+ STICKER_DATA_TYPE_GROUP,
+ STICKER_DATA_TYPE_KEYWORD,
+ STICKER_DATA_TYPE_DATE,
+} STICKER_DAT_TYPE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_DEFS_H__ */
\ No newline at end of file
--- /dev/null
+SET(SRCS
+ sticker_consumer.c
+ ../client/sticker_data.c
+ ../client/sticker_dbus.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+## Add definitions ##
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+## sticker consumer library ##
+ADD_LIBRARY(${PROJECT_NAME}-consumer SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}-consumer ${pkgs_LDFLAGS})
+
+## Install library files ##
+INSTALL(TARGETS ${PROJECT_NAME}-consumer DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <dlog.h>
+#include <gio/gio.h>
+#include <dbus/dbus.h>
+#include <cynara-client.h>
+#include <cynara-error.h>
+#include <cynara-session.h>
+
+#include "sticker_consumer.h"
+#include "sticker_consumer_main.h"
+#include "sticker_dbus.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKER_CONSUMER"
+
+static cynara *p_cynara = NULL;
+
+static void _free_sticker_data(sticker_data_h sticker_data)
+{
+ if (sticker_data->app_id) {
+ free(sticker_data->app_id);
+ sticker_data->app_id = NULL;
+ }
+
+ if (sticker_data->uri) {
+ free(sticker_data->uri);
+ sticker_data->uri = NULL;
+ }
+
+ if (sticker_data->thumbnail) {
+ free(sticker_data->thumbnail);
+ sticker_data->thumbnail = NULL;
+ }
+
+ if (sticker_data->keyword) {
+ g_list_free_full(sticker_data->keyword, free);
+ sticker_data->keyword = NULL;
+ }
+
+ if (sticker_data->group) {
+ free(sticker_data->group);
+ sticker_data->group = NULL;
+ }
+
+ if (sticker_data->description) {
+ free(sticker_data->description);
+ sticker_data->description = NULL;
+ }
+
+ if (sticker_data->date) {
+ free(sticker_data->date);
+ sticker_data->date = NULL;
+ }
+
+ free(sticker_data);
+ sticker_data = NULL;
+}
+
+static int _cynara_initialize()
+{
+ int ret = cynara_initialize(&p_cynara, NULL);
+ if (ret != CYNARA_API_SUCCESS)
+ LOGE("Failed to cynara initialize");
+
+ return ret;
+}
+
+static int _check_privilege(const char *uid, const char *privilege)
+{
+ int ret;
+ FILE *fp = NULL;
+ char label_path[1024] = "/proc/self/attr/current";
+ char smack_label[1024] = {'\0',};
+
+ if (!p_cynara) {
+ return -1;
+ }
+
+ fp = fopen(label_path, "r");
+ if (fp != NULL) {
+ ret = fread(smack_label, 1, sizeof(smack_label), fp);
+ if (ret <= 0)
+ LOGE("Failed to fread");
+
+ fclose(fp);
+ }
+
+ pid_t pid = getpid();
+ char *session = cynara_session_from_pid(pid);
+ ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
+ if (session)
+ free(session);
+
+ if (ret != CYNARA_API_ACCESS_ALLOWED) {
+ LOGE("Access denied. The result of cynara_check() : %d.", ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void _cynara_deinitialize()
+{
+ if (p_cynara)
+ cynara_finish(p_cynara);
+
+ p_cynara = NULL;
+}
+
+static int _sticker_check_privilege() {
+ char uid[16];
+ int ret = STICKER_ERROR_NONE;
+
+ if (_cynara_initialize() != CYNARA_API_SUCCESS)
+ return STICKER_ERROR_PERMISSION_DENIED;
+
+ snprintf(uid, 16, "%d", getuid());
+ if (_check_privilege(uid, STICKER_PRIVILEGE_MEDIASTORAGE) < 0) {
+ LOGE("Permission is denied");
+ ret = STICKER_ERROR_PERMISSION_DENIED;
+ }
+
+ _cynara_deinitialize();
+
+ return ret;
+}
+
+EXPORT_API int sticker_consumer_create(sticker_consumer_h *consumer_handle)
+{
+ int ret;
+
+ if (!consumer_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ if (_sticker_check_privilege() != STICKER_ERROR_NONE)
+ return STICKER_ERROR_PERMISSION_DENIED;
+
+ struct sticker_consumer_s *consumer_struct = (sticker_consumer_h)calloc(1, sizeof(struct sticker_consumer_s));
+
+ if (!consumer_struct)
+ return STICKER_ERROR_OUT_OF_MEMORY;
+
+ ret = sticker_dbus_init(&consumer_struct->gdbus_connection, &consumer_struct->server_watcher_id,
+ &consumer_struct->monitor_id, &consumer_struct->server_monitor_id, STICKER_CLIENT_LIB_CONSUMER, (void *)consumer_struct);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to initialize dbus : %d", ret);
+ free(consumer_struct);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ *consumer_handle = consumer_struct;
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_consumer_destroy(sticker_consumer_h consumer_handle)
+{
+ LOGD("consumer_handle : %p", consumer_handle);
+ int ret;
+
+ if (!consumer_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_shutdown(consumer_handle->gdbus_connection, &consumer_handle->server_monitor_id, &consumer_handle->monitor_id);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to finalize dbus : %d", ret);
+ free(consumer_handle);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ if (consumer_handle->gdbus_connection)
+ g_object_unref(consumer_handle->gdbus_connection);
+
+ free(consumer_handle);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_consumer_data_foreach_all(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_consumer_data_foreach_cb callback, void *user_data)
+{
+ int ret;
+ int info_id;
+ int sticker_count = 0;
+ GVariantIter *id_iter = NULL;
+
+ if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_get_all_sticker_info(consumer_handle->gdbus_connection, offset, count, &id_iter);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get all sticker information : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if (id_iter) {
+ while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+ if (!sticker_data) {
+ ret = STICKER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
+ if (ret == STICKER_ERROR_NONE) {
+ sticker_count++;
+ callback(sticker_data, user_data);
+ _free_sticker_data(sticker_data);
+ } else {
+ _free_sticker_data(sticker_data);
+ goto cleanup;
+ }
+ }
+ }
+
+ *result = sticker_count;
+
+cleanup:
+ if (id_iter)
+ g_variant_iter_free(id_iter);
+
+ return ret;
+}
+
+EXPORT_API int sticker_consumer_data_foreach_by_keyword(sticker_consumer_h consumer_handle, int offset, int count, int *result, const char *keyword, sticker_consumer_data_foreach_cb callback, void *user_data)
+{
+ int ret;
+ int info_id;
+ int sticker_count = 0;
+ GVariantIter *id_iter = NULL;
+
+ if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !keyword || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_get_sticker_info_by_keyword(consumer_handle->gdbus_connection, keyword, offset, count, &id_iter);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get sticker information by keyword : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if (id_iter) {
+ while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+ if (!sticker_data) {
+ ret = STICKER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
+ if (ret == STICKER_ERROR_NONE) {
+ sticker_count++;
+ callback(sticker_data, user_data);
+ _free_sticker_data(sticker_data);
+ } else {
+ _free_sticker_data(sticker_data);
+ goto cleanup;
+ }
+ }
+ }
+
+ *result = sticker_count;
+
+cleanup:
+ if (id_iter)
+ g_variant_iter_free(id_iter);
+
+ return ret;
+}
+
+EXPORT_API int sticker_consumer_data_foreach_by_group(sticker_consumer_h consumer_handle, int offset, int count, int *result, const char *group, sticker_consumer_data_foreach_cb callback, void *user_data)
+{
+ int ret;
+ int info_id;
+ int sticker_count = 0;
+ GVariantIter *id_iter = NULL;
+
+ if (!consumer_handle || (offset < 0) || (count <= 0) || !result || !group || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_get_sticker_info_by_group(consumer_handle->gdbus_connection, group, offset, count, &id_iter);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get sticker information by group : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if (id_iter) {
+ while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+ if (!sticker_data) {
+ ret = STICKER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
+ if (ret == STICKER_ERROR_NONE) {
+ sticker_count++;
+ callback(sticker_data, user_data);
+ _free_sticker_data(sticker_data);
+ } else {
+ _free_sticker_data(sticker_data);
+ goto cleanup;
+ }
+ }
+ }
+
+ *result = sticker_count;
+
+cleanup:
+ if (id_iter)
+ g_variant_iter_free(id_iter);
+
+ return ret;
+}
+
+EXPORT_API int sticker_consumer_data_foreach_by_type(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_data_uri_type_e type, sticker_consumer_data_foreach_cb callback, void *user_data)
+{
+ int ret;
+ int info_id;
+ int sticker_count = 0;
+ GVariantIter *id_iter = NULL;
+
+ if (!consumer_handle || (offset < 0) || (count <= 0) || !result || (type < 1) || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_get_sticker_info_by_type(consumer_handle->gdbus_connection, type, offset, count, &id_iter);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get sticker information by group : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if (id_iter) {
+ while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+ if (!sticker_data) {
+ ret = STICKER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_info_by_record_id(consumer_handle->gdbus_connection, sticker_data, info_id);
+ if (ret == STICKER_ERROR_NONE) {
+ sticker_count++;
+ callback(sticker_data, user_data);
+ _free_sticker_data(sticker_data);
+ } else {
+ _free_sticker_data(sticker_data);
+ goto cleanup;
+ }
+ }
+ }
+
+ *result = sticker_count;
+
+cleanup:
+ if (id_iter)
+ g_variant_iter_free(id_iter);
+
+ return ret;
+}
+
+EXPORT_API int sticker_consumer_group_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_group_list_foreach_cb callback, void *user_data)
+{
+ int ret;
+ GList *list = NULL;
+
+ if (!consumer_handle || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_get_group_list(consumer_handle->gdbus_connection, &list);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get group list : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
+ callback((const char *)tmp->data, user_data);
+ }
+
+cleanup:
+ if (list)
+ g_list_free_full(list, free);
+
+ return ret;
+}
+
+EXPORT_API int sticker_consumer_keyword_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_keyword_list_foreach_cb callback, void *user_data)
+{
+ int ret;
+ GList *list = NULL;
+
+ if (!consumer_handle || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_get_keyword_list(consumer_handle->gdbus_connection, &list);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get keyword list : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ for(GList *tmp = g_list_first(list); tmp != NULL; tmp=tmp->next) {
+ callback((const char *)tmp->data, user_data);
+ }
+
+cleanup:
+ if (list)
+ g_list_free_full(list, free);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_CONSUMER_MAIN_H__
+#define __TIZEN_UIX_STICKER_CONSUMER_MAIN_H__
+
+#include <gio/gio.h>
+#include <dbus/dbus.h>
+#include "sticker_consumer.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct sticker_consumer_s {
+ GDBusConnection *gdbus_connection;
+ guint server_watcher_id;
+ int monitor_id;
+ int server_monitor_id;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_CONSUMER_MAIN_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_CONSUMER_DOC_H__
+#define __TIZEN_UIX_STICKER_CONSUMER_DOC_H__
+
+
+/**
+ * @ingroup CAPI_UIX_STICKER_MODULE
+ * @defgroup CAPI_UIX_STICKER_CONSUMER_MODULE Sticker Consumer
+ * @brief The @ref CAPI_UIX_STICKER_CONSUMER_MODULE API provides the functions to retrieve the sticker information.
+ * @section CAPI_UIX_STICKER_CONSUMER_MODULE_HEADER Required Header
+ * \#include <sticker_consumer.h>
+ *
+ * @section CAPI_UIX_STICKER_CONSUMER_MODULE_OVERVIEW Overview
+ * The @ref CAPI_UIX_STICKER_CONSUMER_MODULE API provides the functions to retrieve the sticker information stored by the provider application.
+ * The application that use stickers can retrieve the sticker information using group name, keyword, and so on.
+ */
+
+
+#endif /* __TIZEN_UIX_STICKER_CONSUMER_DOC_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_DATA_DOC_H__
+#define __TIZEN_UIX_STICKER_DATA_DOC_H__
+
+
+/**
+ * @ingroup CAPI_UIX_STICKER_MODULE
+ * @defgroup CAPI_UIX_STICKER_DATA_MODULE Sticker Data
+ * @brief The @ref CAPI_UIX_STICKER_DATA_MODULE API provides the functions for setting and getting sticker attributes.
+ * @section CAPI_UIX_STICKER_DATA_MODULE_HEADER Required Header
+ * \#include <sticker_data.h>
+ *
+ * @section CAPI_UIX_STICKER_DATA_MODULE_OVERVIEW Overview
+ * The @ref CAPI_UIX_STICKER_DATA_MODULE API provides the functions to set and get sticker attributes:
+ * <ul>
+ * <li>Name of the provider application</li>
+ * <li>URI type</li>
+ * <li>URI</li>
+ * <li>Keyword</li>
+ * <li>Group name</li>
+ * <li>Thumbnail path</li>
+ * <li>Description</li>
+ * <li>Last updated date</li>
+ * </ul>
+ */
+
+
+#endif /* __TIZEN_UIX_STICKER_DATA_DOC_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_DOC_H__
+#define __TIZEN_UIX_STICKER_DOC_H__
+
+
+/**
+ * @ingroup CAPI_UIX_FRAMEWORK
+ * @defgroup CAPI_UIX_STICKER_MODULE Sticker
+ * @brief The @ref CAPI_UIX_STICKER_MODULE API provides the functions to manage and retrieve sticker information.
+ *
+ * @section CAPI_UIX_STICKER_MODULE_OVERVIEW Overview
+ * Using sticker library, a sticker application can provide sticker information to applications that want to read the sticker information as the standard specification.
+ */
+
+
+#endif /* __TIZEN_UIX_STICKER_DOC_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_PROVIDER_DOC_H__
+#define __TIZEN_UIX_STICKER_PROVIDER_DOC_H__
+
+
+/**
+ * @ingroup CAPI_UIX_STICKER_MODULE
+ * @defgroup CAPI_UIX_STICKER_PROVIDER_MODULE Sticker Provider
+ * @brief The @ref CAPI_UIX_STICKER_PROVIDER_MODULE API provides the functions to create/update/delete the sticker information.
+ * @section CAPI_UIX_STICKER_PROVIDER_MODULE_HEADER Required Header
+ * \#include <sticker_provider.h>
+ *
+ * @section CAPI_UIX_STICKER_PROVIDER_MODULE_OVERVIEW Overview
+ * The sticker provider application can manager sticker information using @ref CAPI_UIX_STICKER_PROVIDER_MODULE APIs.
+ * However, the provider application can only update and delete their own stickers.
+ */
+
+
+#endif /* __TIZEN_UIX_STICKER_PROVIDER_DOC_H__ */
\ No newline at end of file
--- /dev/null
+## configure pkgconfig files ##
+CONFIGURE_FILE(capi-ui-sticker-consumer.pc.in "${PROJECT_NAME}-consumer.pc" @ONLY)
+CONFIGURE_FILE(capi-ui-sticker-provider.pc.in "${PROJECT_NAME}-provider.pc" @ONLY)
+
+## Install header, pc files ##
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-consumer.pc" DESTINATION ${LIBDIR}/pkgconfig)
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/${PROJECT_NAME}-provider.pc" DESTINATION ${LIBDIR}/pkgconfig)
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/sticker_error.h" DESTINATION ${INCLUDEDIR})
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/sticker_data.h" DESTINATION ${INCLUDEDIR})
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/sticker_consumer.h" DESTINATION ${INCLUDEDIR})
+INSTALL(FILES "${CMAKE_BINARY_DIR}/include/sticker_provider.h" DESTINATION ${INCLUDEDIR})
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@-consumer
+Description: Sticker Consumer APIs
+Requires: glib-2.0 dbus-1
+Version: @VERSION@
+Libs: -L${libdir} -lcapi-ui-sticker-consumer
+Cflags: -I${includedir}
\ No newline at end of file
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@-provider
+Description: Sticker Provider APIs
+Requires: glib-2.0 dbus-1
+Version: @VERSION@
+Libs: -L${libdir} -lcapi-ui-sticker-provider
+Cflags: -I${includedir}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018 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 __TIZEN_UIX_STICKER_CONSUMER_H__
+#define __TIZEN_UIX_STICKER_CONSUMER_H__
+
+#include <sticker_error.h>
+#include <sticker_data.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file sticker_consumer.h
+ * @brief This file contains sticker consumer's APIs.
+ */
+
+/**
+ * @addtogroup CAPI_UIX_STICKER_CONSUMER_MODULE
+ * @{
+ */
+
+/**
+ * @brief The sticker consumer handle.
+ * @since_tizen 5.5
+ */
+typedef struct sticker_consumer_s *sticker_consumer_h;
+
+/**
+ * @brief Called to retrieve all sticker data in the sticker database.
+ * @details The sticker_consumer_data_foreach_all(), sticker_consumer_data_foreach_by_keyword(), sticker_consumer_data_foreach_by_group(),
+ * sticker_consumer_data_foreach_by_type() must be called to invoke this callback function, synchronously.
+ * @since_tizen 5.5
+ * @remarks @a data_handle should not be freed and can be used only in the callback.
+ * If you want to use it outside of the callback, you need to use a clone which can be obtained sticker_data_clone().
+ * @param[in] data_handle The sticker data handle
+ * @param[in] user_data The user data passed from the foreach function
+ * @pre sticker_consumer_data_foreach_all() will invoke this callback.
+ * @pre sticker_consumer_data_foreach_by_keyword() will invoke this callback.
+ * @pre sticker_consumer_data_foreach_by_group() will invoke this callback.
+ * @pre sticker_consumer_data_foreach_by_type() will invoke this callback.
+ * @see sticker_consumer_data_foreach_all()
+ * @see sticker_consumer_data_foreach_by_keyword()
+ * @see sticker_consumer_data_foreach_by_group()
+ * @see sticker_consumer_data_foreach_by_type()
+ */
+typedef void (*sticker_consumer_data_foreach_cb)(sticker_data_h data_handle, void *user_data);
+
+/**
+ * @brief Called to retrieve all group names in the sticker database.
+ * @details The sticker_consumer_group_list_foreach_all() must be called to invoke this callback function, synchronously.
+ * @since_tizen 5.5
+ * @remarks @a group should not be freed and can be used only in the callback.
+ * @param[in] group The group name of the sticker
+ * @param[in] user_data The user data passed from the foreach function
+ * @pre sticker_consumer_group_list_foreach_all() will invoke this callback.
+ * @see sticker_consumer_group_list_foreach_all()
+ */
+typedef void (*sticker_consumer_group_list_foreach_cb)(const char *group, void *user_data);
+
+/**
+ * @brief Called to retrieve all keywords in the sticker database.
+ * @details The sticker_consumer_keyword_list_foreach_all() must be called to invoke this callback function, synchronously.
+ * @since_tizen 5.5
+ * @remarks @a keyword should not be freed and can be used only in the callback.
+ * @param[in] keyword The keyword of the sticker
+ * @param[in] user_data The user data passed from the foreach function
+ * @pre sticker_consumer_keyword_list_foreach_all() will invoke this callback.
+ * @see sticker_consumer_keyword_list_foreach_all()
+ */
+typedef void (*sticker_consumer_keyword_list_foreach_cb)(const char *keyword, void *user_data);
+
+/**
+ * @brief Creates a sticker consumer handle.
+ * @since_tizen 5.5
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/mediastorage
+ * @remarks If the function succeeds, @a consumer_handle must be released with sticker_consumer_destroy().
+ * @param[out] consumer_handle The sticker consumer handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_consumer_destroy()
+ */
+int sticker_consumer_create(sticker_consumer_h *consumer_handle);
+
+/**
+ * @brief Destroys a sticker consumer handle.
+ * @since_tizen 5.5
+ * @param[in] consumer_handle The sticker consumer handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_consumer_create()
+ */
+int sticker_consumer_destroy(sticker_consumer_h consumer_handle);
+
+/**
+ * @brief Retrieves all sticker data in the sticker database.
+ * @details If you set the @a offset as @c 10 and @a count as @c 10, then only retrieved data from @c 10 to @c 19 will be invoked.
+ * @since_tizen 5.5
+ * @remarks It is not an error if @a result is smaller than @a count.
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] offset The start position (Starting from zero)
+ * @param[in] count The number of stickers to be retrieved with respect to the offset
+ * @param[out] result The number of stickers retrieved (zero indicates that no data was found)
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_data_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_data_foreach_cb()
+ */
+int sticker_consumer_data_foreach_all(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_consumer_data_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Retrieves all sticker data in the sticker database using keyword.
+ * @details If you set the @a offset as @c 10 and @a count as @c 10, then only retrieved data from @c 10 to @c 19 will be invoked.
+ * @since_tizen 5.5
+ * @remarks It is not an error if @a result is smaller than @a count.
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] offset The start position (Starting from zero)
+ * @param[in] count The number of stickers to be retrieved with respect to the offset
+ * @param[out] result The number of stickers retrieved (zero indicates that no data was found)
+ * @param[in] keyword The keyword of the sticker for getting sticker data
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_data_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_data_foreach_cb()
+ */
+int sticker_consumer_data_foreach_by_keyword(sticker_consumer_h consumer_handle, int offset, int count, int *result, const char *keyword, sticker_consumer_data_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Retrieves all sticker data in the sticker database using group name.
+ * @details If you set the @a offset as @c 10 and @a count as @c 10, then only retrieved data from @c 10 to @c 19 will be invoked.
+ * @since_tizen 5.5
+ * @remarks It is not an error if @a result is smaller than @a count.
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] offset The start position (Starting from zero)
+ * @param[in] count The number of stickers to be retrieved with respect to the offset
+ * @param[out] result The number of stickers retrieved (zero indicates that no data was found)
+ * @param[in] group The group name of the sticker for getting sticker data
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_data_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_data_foreach_cb()
+ */
+int sticker_consumer_data_foreach_by_group(sticker_consumer_h consumer_handle, int offset, int count, int *result, const char *group, sticker_consumer_data_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Retrieves all sticker data in the sticker database using URI type.
+ * @details If you set the @a offset as @c 10 and @a count as @c 10, then only retrieved data from @c 10 to @c 19 will be invoked.
+ * @since_tizen 5.5
+ * @remarks It is not an error if @a result is smaller than @a count.
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] offset The start position (Starting from zero)
+ * @param[in] count The number of stickers to be retrieved with respect to the offset
+ * @param[out] result The number of stickers retrieved (zero indicates that no data was found)
+ * @param[in] type The URI type of the sticker for getting sticker data
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_data_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_data_foreach_cb()
+ */
+int sticker_consumer_data_foreach_by_type(sticker_consumer_h consumer_handle, int offset, int count, int *result, sticker_data_uri_type_e type, sticker_consumer_data_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Retrieves all group name in the sticker database.
+ * @since_tizen 5.5
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_group_list_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_group_list_foreach_cb()
+ */
+int sticker_consumer_group_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_group_list_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Retrieves all keyword in the sticker database.
+ * @since_tizen 5.5
+ * @param[in] consumer_handle The sticker consumer handle
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_consumer_keyword_list_foreach_cb() repeatedly for getting data.
+ * @see sticker_consumer_keyword_list_foreach_cb()
+ */
+int sticker_consumer_keyword_list_foreach_all(sticker_consumer_h consumer_handle, sticker_consumer_keyword_list_foreach_cb callback, void *user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_CONSUMER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_DATA_H__
+#define __TIZEN_UIX_STICKER_DATA_H__
+
+#include <sticker_error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file sticker_data.h
+ * @brief This file contains sticker data APIs and related enumeration.
+ */
+
+/**
+ * @addtogroup CAPI_UIX_STICKER_DATA_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for sticker URI type.
+ *
+ * @since_tizen 5.5
+ */
+typedef enum {
+ STICKER_DATA_URI_LOCAL_PATH = 1, /**< Local path URI */
+ STICKER_DATA_URI_WEB_RESOURCE, /**< Web resource URI */
+} sticker_data_uri_type_e;
+
+/**
+ * @brief The sticker data handle.
+ * @since_tizen 5.5
+ */
+typedef struct sticker_data_s *sticker_data_h;
+
+/**
+ * @brief Called to retrieve the keyword of the sticker.
+ * @details The sticker_data_foreach_keyword() must be called to invoke this callback function, synchronously.
+ * @since_tizen 5.5
+ * @remarks @a keyword should not be freed and can be used only in the callback.
+ * @param[in] keyword The sticker keyword
+ * @param[in] user_data The user data passed from the foreach function
+ * @pre sticker_data_foreach_keyword() will invoke this callback.
+ * @see sticker_data_foreach_keyword()
+ */
+typedef void (*sticker_data_keyword_foreach_cb)(const char *keyword, void *user_data);
+
+/**
+ * @brief Creates a sticker data handle.
+ * @since_tizen 5.5
+ * @remarks If the function succeeds, @a data_handle must be released with sticker_data_destroy().
+ * @param[out] data_handle The sticker data handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_data_destroy()
+ */
+int sticker_data_create(sticker_data_h *data_handle);
+
+/**
+ * @brief Destroys a sticker data handle.
+ * @since_tizen 5.5
+ * @param[in] data_handle The sticker data handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_create()
+ */
+int sticker_data_destroy(sticker_data_h data_handle);
+
+/**
+ * @brief Clones a sticker data handle.
+ * @since_tizen 5.5
+ * @remarks If the function succeeds, @a target_handle must be released with sticker_data_destroy().
+ * @param[in] origin_handle The sticker data handle
+ * @param[out] target_handle The sticker data handle to be cloned
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @see sticker_data_destroy()
+ */
+int sticker_data_clone(sticker_data_h origin_handle, sticker_data_h *target_handle);
+
+/**
+ * @brief Gets the name of the sticker provider application from sticker data handle.
+ * @since_tizen 5.5
+ * @remarks @a app_id must be released using free().
+ * @param[in] data_handle The sticker data handle
+ * @param[out] app_id The name of the application that provides sticker information
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ */
+int sticker_data_get_app_id(sticker_data_h data_handle, char **app_id);
+
+/**
+ * @brief Sets the URI and URI type of the sticker.
+ * @details @a uri must be a relative path like '/res/smile.png' when the type of URI is local path.
+ * @since_tizen 5.5
+ * @remarks @a uri must have a non-null value and must be an existing file. If not, the error as invalid parameter will be returned.
+ * @param[in] data_handle The sticker data handle
+ * @param[in] type The URI type to be saved
+ * @param[in] uri The URI to be saved
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_data_get_uri()
+ */
+int sticker_data_set_uri(sticker_data_h data_handle, sticker_data_uri_type_e type, const char *uri);
+
+/**
+ * @brief Gets the URI and URI type from sticker data handle.
+ * @since_tizen 5.5
+ * @remarks @a uri must be released using free().
+ * @param[in] data_handle The sticker data handle
+ * @param[out] type The URI type
+ * @param[out] uri The URI
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_data_set_uri()
+ */
+int sticker_data_get_uri(sticker_data_h data_handle, sticker_data_uri_type_e *type, char **uri);
+
+/**
+ * @brief Retrieves all keywords of the sticker using callback function.
+ * @since_tizen 5.5
+ * @param[in] data_handle The sticker data handle
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_data_keyword_foreach_cb() repeatedly for getting keywords.
+ * @see sticker_data_keyword_foreach_cb()
+ * @see sticker_data_add_keyword()
+ * @see sticker_data_remove_keyword()
+ */
+int sticker_data_foreach_keyword(sticker_data_h data_handle, sticker_data_keyword_foreach_cb callback, void *user_data);
+
+/**
+ * @brief Adds a keyword of the sticker to the list.
+ * @since_tizen 5.5
+ * @remarks @a keyword must have a non-null value and can not have duplicate value. If not, the error as invalid parameter will be returned.
+ * @param[in] data_handle The sticker data handle
+ * @param[in] keyword The keyword to be saved
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_keyword_foreach_cb()
+ * @see sticker_data_foreach_keyword()
+ * @see sticker_data_remove_keyword()
+ */
+int sticker_data_add_keyword(sticker_data_h data_handle, const char *keyword);
+
+/**
+ * @brief Removes a keyword of the sticker from the list.
+ * @since_tizen 5.5
+ * @remarks @a keyword must exist value in the list. If not, the error as invalid parameter will be returned.
+ * @param[in] data_handle The sticker data handle
+ * @param[in] keyword The keyword to be removed
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_keyword_foreach_cb()
+ * @see sticker_data_foreach_keyword()
+ * @see sticker_data_add_keyword()
+ */
+int sticker_data_remove_keyword(sticker_data_h data_handle, const char *keyword);
+
+/**
+ * @brief Sets the group name of the sticker.
+ * @since_tizen 5.5
+ * @remarks @a group must have a non-null value. If not, the error as invalid parameter will be returned.
+ * @param[in] data_handle The sticker data handle
+ * @param[in] group The group name to be saved
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_get_group()
+ */
+int sticker_data_set_group_name(sticker_data_h data_handle, const char *group);
+
+/**
+ * @brief Gets the group name from sticker data handle.
+ * @since_tizen 5.5
+ * @remarks @a group must be released using free().
+ * @param[in] data_handle The sticker data handle
+ * @param[out] group The group name
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_data_set_group()
+ */
+int sticker_data_get_group_name(sticker_data_h data_handle, char **group);
+
+/**
+ * @brief Sets the thumbnail local path of the sticker.
+ * @details @a thumbnail must be a relative path like '/res/smile_thumbnail.png'.
+ * @since_tizen 5.5
+ * @remarks @a thumbnail must have a non-null value and must be an existing file. If not, the error as invalid parameter will be returned.
+ * @param[in] data_handle The sticker data handle
+ * @param[in] thumbnail The thumbnail path to be saved
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_get_thumbnail()
+ */
+int sticker_data_set_thumbnail(sticker_data_h data_handle, const char *thumbnail);
+
+/**
+ * @brief Gets the thumbnail local path from sticker data handle.
+ * @details If the thumbnail is empty, the result will be an empty string.
+ * @since_tizen 5.5
+ * @remarks @a thumbnail must be released using free().
+ * @param[in] data_handle The sticker data handle
+ * @param[out] thumbnail The thumbnail path
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_set_thumbnail()
+ */
+int sticker_data_get_thumbnail(sticker_data_h data_handle, char **thumbnail);
+
+/**
+ * @brief Sets the description of the sticker.
+ * @since_tizen 5.5
+ * @remarks @a description must have a non-null value. If not, the error as invalid parameter will be returned.
+ * @param[in] data_handle The sticker data handle
+ * @param[in] description The description to be saved
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_get_description()
+ */
+int sticker_data_set_description(sticker_data_h data_handle, const char *description);
+
+/**
+ * @brief Gets the description from sticker data handle.
+ * @details If the description is empty, the result will be an empty string.
+ * @since_tizen 5.5
+ * @remarks @a description must be released using free().
+ * @param[in] data_handle The sticker data handle
+ * @param[out] description The description of the sticker
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see sticker_data_set_description()
+ */
+int sticker_data_get_description(sticker_data_h data_handle, char **description);
+
+/**
+ * @brief Gets the last updated date from sticker data handle.
+ * @details The format of @a date is YYYY-MM-DD HH:MM:SS.
+ * @since_tizen 5.5
+ * @remarks @a date must be released using free().
+ * @param[in] data_handle The sticker data handle
+ * @param[out] date The last updated date
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ */
+int sticker_data_get_date(sticker_data_h data_handle, char **date);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_DATA_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_ERROR_H__
+#define __TIZEN_UIX_STICKER_ERROR_H__
+
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file sticker_error.h
+ * @brief This file contains sticker error enumeration.
+ */
+
+/**
+ * @addtogroup CAPI_UIX_STICKER_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for sticker function error.
+ *
+ * @since_tizen 5.5
+ */
+typedef enum {
+ STICKER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ STICKER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+ STICKER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
+ STICKER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
+ STICKER_ERROR_OPERATION_FAILED = TIZEN_ERROR_STICKER | 0x0001, /**< Operation failed */
+} sticker_error_e;
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_ERROR_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018 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 __TIZEN_UIX_STICKER_PROVIDER_H__
+#define __TIZEN_UIX_STICKER_PROVIDER_H__
+
+#include <sticker_error.h>
+#include <sticker_data.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file sticker_provider.h
+ * @brief This file contains sticker provider's APIs.
+ */
+
+/**
+ * @addtogroup CAPI_UIX_STICKER_PROVIDER_MODULE
+ * @{
+ */
+
+/**
+ * @brief The sticker provider handle.
+ * @since_tizen 5.5
+ */
+typedef struct sticker_provider_s *sticker_provider_h;
+
+/**
+ * @brief Called to retrieve all sticker data in the sticker database.
+ * @details The sticker_provider_data_foreach_all() must be called to invoke this callback function, synchronously.
+ * @since_tizen 5.5
+ * @remarks @a data_handle should not be freed and can be used only in the callback.
+ * If you want to use it outside of the callback, you need to use a clone which can be obtained sticker_data_clone().
+ * @param[in] data_handle The sticker data handle
+ * @param[in] user_data The user data passed from the foreach function
+ * @pre sticker_provider_data_foreach_all() will invoke this callback.
+ * @see sticker_provider_data_foreach_all()
+ */
+typedef void (*sticker_provider_data_foreach_cb)(sticker_data_h data_handle, void *user_data);
+
+/**
+ * @brief Called when inserting sticker data is finished.
+ * @details The following error codes can be received: \n
+ * #STICKER_ERROR_NONE Successful \n
+ * #STICKER_ERROR_OPERATION_FAILED Operation failed \n
+ * @since_tizen 5.5
+ * @param[in] error The sticker error code
+ * @param[in] user_data The user data passed from the foreach function
+ * @pre sticker_privider_insert_data_by_json_file() will invoke this callback.
+ * @see sticker_privider_insert_data_by_json_file()
+ */
+typedef void (*sticker_provider_insert_finished_cb)(sticker_error_e error, void *user_data);
+
+/**
+ * @brief Creates a sticker provider handle.
+ * @since_tizen 5.5
+ * @remarks If the function succeeds, @a provider_handle must be released with sticker_provider_destroy().
+ * @param[out] provider_handle The sticker provider handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_provider_destroy()
+ */
+int sticker_provider_create(sticker_provider_h *provider_handle);
+
+/**
+ * @brief Destroys a sticker provider handle.
+ * @since_tizen 5.5
+ * @param[in] provider_handle The sticker provider handle
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_provider_create()
+ */
+int sticker_provider_destroy(sticker_provider_h provider_handle);
+
+/**
+ * @brief Inserts a sticker data to the sticker database.
+ * @since_tizen 5.5
+ * @remarks All data except thumbnail and description must be set in the @a data_handle to insert the sticker data.
+ * If the uri type is @a STICKER_DATA_URI_LOCAL_PATH, the sticker file is copied to a sticker directory.
+ * It is recommended to delete your sticker file after inserting a sticker data.
+ * @param[in] provider_handle The sticker provider handle
+ * @param[in] data_handle The sticker data handle to be saved
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_provider_update_data()
+ * @see sticker_provider_delete_data()
+ */
+int sticker_provider_insert_data(sticker_provider_h provider_handle, sticker_data_h data_handle);
+
+/**
+ * @brief Inserts a sticker data using json file.
+ * @details @a json_path must be a relative path like '/data/message_sticker.json'.
+ * @since_tizen 5.5
+ * @remarks All data except thumbnail and description must be set in the json file to insert the sticker data.
+ * @a json_path must have a non-null value and must be an existing file. If not, the error as invalid parameter will be returned.
+ * If the uri type is @a STICKER_DATA_URI_LOCAL_PATH, the sticker file is copied to a sticker directory.
+ * It is recommended to delete your sticker files after inserting a sticker data.
+ * @param[in] provider_handle The sticker provider handle
+ * @param[in] json_path The path of json file containing sticker information to be saved
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_provider_insert_finished_cb().
+ * @see sticker_provider_insert_finished_cb()
+ *
+ * @code
+ //json file format
+ {
+ "sticker":
+ [
+ {
+ "type" : 1,
+ "uri" : "/res/face/heart_eyes.png",
+ "keyword" : ["heart eyes", "love", "cute"],
+ "group" : "face",
+ "thumbnail" : "/res/face/thumbnail/heart_eyes.png",
+ "description" : "Smiling face with heart eyes emoji."
+ },
+ {
+ "type" : 2,
+ "uri" : "https://samsung.com/example/01/high_five.png",
+ "keyword" : ["smile", "high five"],
+ "group" : "face",
+ "thumbnail" : "",
+ "description" : "Smiling face with high five emoji."
+ },
+ .....
+ {
+ .....
+ }
+ ]
+ }
+ * @endcode
+ */
+int sticker_privider_insert_data_by_json_file(sticker_provider_h provider_handle, const char *json_path, sticker_provider_insert_finished_cb callback, void *user_data);
+
+/**
+ * @brief Updates a sticker data in the sticker database.
+ * @since_tizen 5.5
+ * @param[in] provider_handle The sticker provider handle
+ * @param[in] data_handle The sticker data handle to be updated
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_provider_insert_data()
+ * @see sticker_provider_delete_data()
+ */
+int sticker_provider_update_data(sticker_provider_h provider_handle, sticker_data_h data_handle);
+
+/**
+ * @brief Deletes a sticker data in the sticker database.
+ * @since_tizen 5.5
+ * @remarks The @a sticker_id must be the ID of the sticker stored in the sticker database.
+ * @param[in] provider_handle The sticker provider handle
+ * @param[in] data_handle The sticker data handle to be deleted
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @see sticker_provider_insert_data()
+ * @see sticker_provider_update_data()
+ */
+int sticker_provider_delete_data(sticker_provider_h provider_handle, sticker_data_h data_handle);
+
+/**
+ * @brief Gets the count of stickers stored by the provider application.
+ * @since_tizen 5.5
+ * @param[in] provider_handle The sticker provider handle
+ * @param[out] count The number of stickers
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ */
+int sticker_provider_get_sticker_count(sticker_provider_h provider_handle, int *count);
+
+/**
+ * @brief Retrieves all sticker data in the sticker database.
+ * @details If you set the @a offset as @c 10 and @a count as @c 10, then only searched data from @c 10 to @c 19 will be invoked.
+ * @since_tizen 5.5
+ * @remarks It is not an error if @a result is smaller than @a count.
+ * @param[in] provider_handle The sticker provider handle
+ * @param[in] offset The start position (Starting from zero)
+ * @param[in] count The number of stickers to be searched with respect to the offset
+ * @param[out] result The number of stickers retrieved (zero indicates that no data was found)
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return 0 on success, otherwise a negative error value
+ * @retval #STICKER_ERROR_NONE Successful
+ * @retval #STICKER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #STICKER_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #STICKER_ERROR_OPERATION_FAILED Operation failed
+ * @post This function invokes sticker_provider_data_foreach_cb() repeatedly for getting data.
+ * @see sticker_provider_data_foreach_cb()
+ */
+int sticker_provider_data_foreach_all(sticker_provider_h provider_handle, int offset, int count, int *result, sticker_provider_data_foreach_cb callback, void *user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_PROVIDER_H__ */
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+
+<busconfig>
+ <policy group="users">
+ <allow own="org.tizen.sticker.server"/>
+ <allow send_destination="org.tizen.sticker.server"/>
+ </policy>
+ <policy group="ui_fw">
+ <allow own="org.tizen.sticker.server"/>
+ <allow send_destination="org.tizen.sticker.server"/>
+ </policy>
+</busconfig>
\ No newline at end of file
--- /dev/null
+[Unit]
+Description=Start the sticker server
+
+[Service]
+User=ui_fw
+Group=ui_fw
+BusName=org.tizen.sticker.server
+Type=dbus
+SmackProcessLabel=System
+ExecStart=/usr/bin/sticker-server
+Restart=on-failure
+RestartSec=2
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+Name: capi-ui-sticker
+Summary: Sticker client library and daemon
+Version: 0.1.0
+Release: 1
+Group: Graphics & UI Framework/Input
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+Source1: capi-ui-sticker.service
+Source2: org.tizen.sticker.server.service
+Source3: capi-ui-sticker.conf
+BuildRequires: cmake, coreutils
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(cynara-client)
+BuildRequires: pkgconfig(cynara-session)
+BuildRequires: pkgconfig(capi-appfw-app-common)
+BuildRequires: pkgconfig(capi-appfw-package-manager)
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(json-glib-1.0)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(gio-unix-2.0)
+BuildRequires: pkgconfig(pkgmgr-info)
+Requires: security-config
+Requires(post): /sbin/ldconfig
+Requires(post): dbus
+Requires(postun): /sbin/ldconfig
+
+%description
+Sticker client library and daemon
+
+%package devel
+Summary: Sticker client library and daemon (Development)
+Group: Graphics & UI Framework/Input
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Sticker client library and daemon (Development)
+
+%prep
+%setup -q -n %{name}-%{version}
+cp %{SOURCE2} .
+
+%build
+
+export CFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror"
+export CXXFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden -Werror"
+export FFLAGS+=" -DTIZEN_DEBUG_ENABLE -fvisibility=hidden"
+
+cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DBINDIR=%{_bindir} -DINCLUDEDIR=%{_includedir} \
+ -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE -DTZ_SYS_BIN=%TZ_SYS_BIN -DTZ_SYS_SHARE=%TZ_SYS_SHARE
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants
+install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/capi-ui-sticker.service
+%install_service multi-user.target.wants capi-ui-sticker.service
+
+mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services
+install -m 0644 %SOURCE2 %{buildroot}%{_datadir}/dbus-1/system-services/org.tizen.sticker.server.service
+
+mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d
+install -m 0644 %SOURCE3 %{buildroot}%{_sysconfdir}/dbus-1/system.d/capi-ui-sticker.conf
+
+%post
+/sbin/ldconfig
+
+mkdir -p -m 0775 %{TZ_SYS_SHARE}/sticker-data
+chown -R ui_fw:ui_fw %{TZ_SYS_SHARE}/sticker-data
+chsmack -t %{TZ_SYS_SHARE}/sticker-data
+chsmack -a "System::Shared" %{TZ_SYS_SHARE}/sticker-data
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%license LICENSE
+%defattr(-,root,root,-)
+%{_libdir}/lib*.so
+%attr(0755,root,root) %{_bindir}/sticker-server
+%attr(0644,root,root) %{_unitdir}/capi-ui-sticker.service
+%attr(0644,root,root) %{_unitdir}/multi-user.target.wants/capi-ui-sticker.service
+%attr(0644,root,root) %{_datadir}/dbus-1/system-services/org.tizen.sticker.server.service
+%config %{_sysconfdir}/dbus-1/system.d/capi-ui-sticker.conf
+%{TZ_SYS_RO_SHARE}/parser-plugins/capi-ui-sticker.info
+%{TZ_SYS_RO_ETC}/package-manager/parserlib/category/libcapi-ui-sticker-parser.so*
+%{TZ_SYS_RO_ETC}/package-manager/parserlib/metadata/libcapi-ui-sticker-parser.so*
+
+%files devel
+%manifest %{name}-devel.manifest
+%defattr(-,root,root,-)
+%{_libdir}/lib*.so
+%{_libdir}/pkgconfig/capi-ui-sticker-consumer.pc
+%{_libdir}/pkgconfig/capi-ui-sticker-provider.pc
+%{_includedir}/sticker_error.h
+%{_includedir}/sticker_data.h
+%{_includedir}/sticker_consumer.h
+%{_includedir}/sticker_provider.h
\ No newline at end of file
--- /dev/null
+[D-BUS Service]
+Name=org.tizen.sticker.server
+Exec=/bin/false
+SystemdService=capi-ui-sticker.service
\ No newline at end of file
--- /dev/null
+SET(SRCS
+ sticker_provider.c
+ ../client/sticker_data.c
+ ../client/sticker_dbus.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+## Add definitions ##
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+## sticker provider library ##
+ADD_LIBRARY(${PROJECT_NAME}-provider SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}-provider ${pkgs_LDFLAGS})
+
+## Install library files ##
+INSTALL(TARGETS ${PROJECT_NAME}-provider DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <app_common.h>
+#include <package_manager.h>
+
+#include "sticker_provider.h"
+#include "sticker_provider_main.h"
+#include "sticker_dbus.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKER_PROVIDER"
+
+static void _free_sticker_data(sticker_data_h sticker_data)
+{
+ if (sticker_data->app_id) {
+ free(sticker_data->app_id);
+ sticker_data->app_id = NULL;
+ }
+
+ if (sticker_data->uri) {
+ free(sticker_data->uri);
+ sticker_data->uri = NULL;
+ }
+
+ if (sticker_data->thumbnail) {
+ free(sticker_data->thumbnail);
+ sticker_data->thumbnail = NULL;
+ }
+
+ if (sticker_data->keyword) {
+ g_list_free_full(sticker_data->keyword, free);
+ sticker_data->keyword = NULL;
+ }
+
+ if (sticker_data->group) {
+ free(sticker_data->group);
+ sticker_data->group = NULL;
+ }
+
+ if (sticker_data->description) {
+ free(sticker_data->description);
+ sticker_data->description = NULL;
+ }
+
+ if (sticker_data->date) {
+ free(sticker_data->date);
+ sticker_data->date = NULL;
+ }
+
+ free(sticker_data);
+ sticker_data = NULL;
+}
+
+EXPORT_API int sticker_provider_create(sticker_provider_h *provider_handle)
+{
+ int ret;
+
+ if (!provider_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ struct sticker_provider_s *provider_struct = (sticker_provider_h)calloc(1, sizeof(struct sticker_provider_s));
+
+ if (!provider_struct)
+ return STICKER_ERROR_OUT_OF_MEMORY;
+
+ ret = sticker_dbus_init(&provider_struct->gdbus_connection, &provider_struct->server_watcher_id,
+ &provider_struct->monitor_id, &provider_struct->server_monitor_id, STICKER_CLIENT_LIB_PROVIDER, (void *)provider_struct);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to initialize dbus : %d", ret);
+ free(provider_struct);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ *provider_handle = provider_struct;
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_provider_destroy(sticker_provider_h provider_handle)
+{
+ LOGD("provider_handle : %p", provider_handle);
+ int ret;
+
+ if (!provider_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_shutdown(provider_handle->gdbus_connection, &provider_handle->server_monitor_id, &provider_handle->monitor_id);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to finalize dbus : %d", ret);
+ free(provider_handle);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ if (provider_handle->gdbus_connection)
+ g_object_unref(provider_handle->gdbus_connection);
+
+ free(provider_handle);
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_provider_insert_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
+{
+ int ret;
+
+ if (!provider_handle || !data_handle || (data_handle->sticker_info_id > 0))
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_insert_sticker_info(provider_handle->gdbus_connection, data_handle);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to insert sticker information : %d", ret);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_privider_insert_data_by_json_file(sticker_provider_h provider_handle, const char *json_path, sticker_provider_insert_finished_cb callback, void *user_data)
+{
+ int ret;
+ char *app_id = NULL;
+ package_info_h package_info = NULL;
+ char *app_path = NULL;
+ char *file_path = NULL;
+
+ if (!provider_handle || !json_path || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = app_get_id(&app_id);
+ if (ret != APP_ERROR_NONE) {
+ LOGE("Failed to get app_id : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if (access(json_path, F_OK) != 0) {
+ ret = package_info_create(app_id, &package_info);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ ret = package_info_get_root_path(package_info, &app_path);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ int path_len = strlen(app_path) + strlen(json_path) + 2;
+ file_path = (char *)calloc(path_len, sizeof(char));
+ if (!file_path) {
+ LOGE("failed to alloc memory");
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if(json_path[0] == '/')
+ snprintf(file_path, path_len, "%s%s",app_path, json_path);
+ else
+ snprintf(file_path, path_len, "%s%s%s",app_path, "/", json_path);
+
+ if (access(file_path, F_OK) != 0) {
+ LOGE("%s does not exist", file_path);
+ ret = STICKER_ERROR_INVALID_PARAMETER;
+ goto cleanup;
+ }
+ } else
+ file_path = strdup(json_path);
+
+ SECURE_LOGD("json path : %s", file_path);
+ ret = sticker_dbus_insert_sticker_info_by_json(provider_handle->gdbus_connection, app_id, file_path);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to load json file : %d", ret);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ provider_handle->insert_finished_cb = callback;
+ provider_handle->insert_finished_cb_user_data = user_data;
+
+cleanup:
+ if (app_id)
+ free(app_id);
+
+ if (package_info)
+ package_info_destroy(package_info);
+
+ if (app_path)
+ free(app_path);
+
+ if (file_path)
+ free(file_path);
+
+ return ret;
+}
+
+EXPORT_API int sticker_provider_update_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
+{
+ int ret;
+
+ if (!provider_handle || !data_handle || (data_handle->sticker_info_id <= 0))
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_update_sticker_info(provider_handle->gdbus_connection, data_handle);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to update sticker information : %d", ret);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_provider_delete_data(sticker_provider_h provider_handle, sticker_data_h data_handle)
+{
+ int ret;
+
+ if (!provider_handle || (data_handle->sticker_info_id <= 0))
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = sticker_dbus_delete_sticker_info(provider_handle->gdbus_connection, data_handle->sticker_info_id);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to delete sticker information : %d", ret);
+ return STICKER_ERROR_OPERATION_FAILED;
+ }
+
+ return STICKER_ERROR_NONE;
+}
+
+EXPORT_API int sticker_provider_get_sticker_count(sticker_provider_h provider_handle, int *count)
+{
+ int ret;
+ char *app_id = NULL;
+
+ if (!provider_handle)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = app_get_id(&app_id);
+ if (ret != APP_ERROR_NONE) {
+ LOGE("Failed to get app_id : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_count(provider_handle->gdbus_connection, app_id, count);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get sticker count : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ }
+
+cleanup:
+ if (app_id)
+ free(app_id);
+
+ return ret;
+}
+
+EXPORT_API int sticker_provider_data_foreach_all(sticker_provider_h provider_handle, int offset, int count, int *result, sticker_provider_data_foreach_cb callback, void *user_data)
+{
+ int ret;
+ int info_id;
+ int sticker_count = 0;
+ char *app_id = NULL;
+ GVariantIter *id_iter = NULL;
+
+ if (!provider_handle || (offset < 0) || (count <= 0) || !result || !callback)
+ return STICKER_ERROR_INVALID_PARAMETER;
+
+ ret = app_get_id(&app_id);
+ if (ret != APP_ERROR_NONE) {
+ LOGE("Failed to get app_id : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_info_by_appid(provider_handle->gdbus_connection, app_id, offset, count, &id_iter);
+ if (ret != STICKER_ERROR_NONE) {
+ LOGE("Failed to get sticker information : %d", ret);
+ ret = STICKER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ if (id_iter) {
+ while (g_variant_iter_loop (id_iter, "(i)", &info_id)) {
+ sticker_data_h sticker_data = (sticker_data_h)calloc(1, sizeof(struct sticker_data_s));
+ if (!sticker_data) {
+ ret = STICKER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ ret = sticker_dbus_get_sticker_info_by_record_id(provider_handle->gdbus_connection, sticker_data, info_id);
+ if (ret == STICKER_ERROR_NONE) {
+ sticker_count++;
+ callback(sticker_data, user_data);
+ _free_sticker_data(sticker_data);
+ } else {
+ _free_sticker_data(sticker_data);
+ goto cleanup;
+ }
+ }
+ }
+
+ *result = sticker_count;
+
+cleanup:
+ if (app_id)
+ free(app_id);
+
+ if (id_iter)
+ g_variant_iter_free(id_iter);
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKER_PROVIDER_MAIN_H__
+#define __TIZEN_UIX_STICKER_PROVIDER_MAIN_H__
+
+#include <gio/gio.h>
+#include <dbus/dbus.h>
+#include "sticker_provider.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct sticker_provider_s {
+ GDBusConnection *gdbus_connection;
+ guint server_watcher_id;
+ int monitor_id;
+ int server_monitor_id;
+ sticker_provider_insert_finished_cb insert_finished_cb;
+ void *insert_finished_cb_user_data;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKER_PROVIDER_MAIN_H__ */
\ No newline at end of file
--- /dev/null
+SET(SRCS
+ stickerd_main.c
+ stickerd_data_manager.c
+ stickerd_db_manager.c
+ stickerd_dbus.c
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+
+## Executable ##
+ADD_EXECUTABLE(sticker-server ${SRCS})
+TARGET_LINK_LIBRARIES(sticker-server ${pkgs_LDFLAGS})
+
+## Install library files ##
+INSTALL(TARGETS sticker-server DESTINATION bin)
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <tzplatform_config.h>
+#include <gio/gunixfdlist.h>
+#include <dlog.h>
+#include <json-glib/json-glib.h>
+#include <package_manager.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#include "stickerd_dbus.h"
+#include "stickerd_data_manager.h"
+#include "stickerd_db_manager.h"
+#include "sticker_defs.h"
+#include "stickerd_error.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKERD_DATA_MANAGER"
+
+#define STICKER_DIRECTORY tzplatform_mkpath(TZ_SYS_SHARE, "sticker-data")
+#define MAX_ERROR_BUFFER 256
+
+static GHashTable *_monitoring_hash;
+static char error_buffer[MAX_ERROR_BUFFER];
+
+static void _on_name_appeared(GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ LOGD("name: %s", name);
+}
+
+static void _on_name_vanished(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ monitoring_info_s *info = (monitoring_info_s *)user_data;
+
+ if (info) {
+ LOGD("name: %s", name);
+ g_bus_unwatch_name(info->watcher_id);
+ delete_monitoring_list(&_monitoring_hash, info->bus_name, info->uid);
+
+ if (info->bus_name)
+ free(info->bus_name);
+ free(info);
+ info = NULL;
+ }
+}
+
+static void _stickerd_client_dbus_method_call_handler(GDBusConnection *conn, const gchar *sender, const gchar *object_path,
+ const gchar *iface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ LOGD("stickerd method_name: %s, sender: %s", method_name, sender);
+
+ GVariant *reply_body = NULL;
+ int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+
+ if (g_strcmp0(method_name, "sticker_service_register") == 0) {
+ ret = stickerd_server_register(parameters, &reply_body, sender,
+ _on_name_appeared, _on_name_vanished, &_monitoring_hash);
+ } else if (g_strcmp0(method_name, "insert_sticker_info") == 0) {
+ ret = stickerd_insert_sticker_info(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_info_by_json") == 0) {
+ ret = stickerd_insert_sticker_info_by_json(parameters, &reply_body, sender);
+ } else if (g_strcmp0(method_name, "delete_sticker_info") == 0) {
+ ret = stickerd_del_sticker_info(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_type") == 0) {
+ ret = stickerd_update_sticker_type(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_uri") == 0) {
+ ret = stickerd_update_sticker_uri(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_thumbnail") == 0) {
+ ret = stickerd_update_sticker_thumbnail(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_description") == 0) {
+ ret = stickerd_update_sticker_description(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_group") == 0) {
+ ret = stickerd_update_sticker_group(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "update_sticker_keyword") == 0) {
+ ret = stickerd_update_sticker_keyword(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_sticker_info") == 0) {
+ ret = stickerd_get_sticker_info(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_group_list") == 0) {
+ ret = stickerd_get_group_list(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_keyword_list") == 0) {
+ ret = stickerd_get_keyword_list(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_sticker_count") == 0) {
+ ret = stickerd_get_sticker_count(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_all_sticker_info") == 0) {
+ ret = stickerd_get_all_sticker_info(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_sticker_info_by_appid") == 0) {
+ ret = stickerd_get_sticker_info_by_app_id(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_sticker_info_by_type") == 0) {
+ ret = stickerd_get_sticker_info_by_type(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_sticker_info_by_group") == 0) {
+ ret = stickerd_get_sticker_info_by_group(parameters, &reply_body);
+ } else if (g_strcmp0(method_name, "get_sticker_info_by_keyword") == 0) {
+ ret = stickerd_get_sticker_info_by_keyword(parameters, &reply_body);
+ }
+
+ if (ret == STICKERD_SERVER_ERROR_NONE) {
+ LOGD("method_call successful, method_name : %s", method_name);
+ g_dbus_method_invocation_return_value(invocation, reply_body);
+ } else {
+ LOGE("method_call failed, method_name : %s", method_name);
+ g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, ret, "sticker error");
+ }
+
+ if (reply_body)
+ g_variant_unref(reply_body);
+}
+
+static const GDBusInterfaceVTable _sticker_interface_vtable = {
+ _stickerd_client_dbus_method_call_handler,
+ NULL,
+ NULL
+};
+
+int stickerd_register_dbus_interface(void)
+{
+ static gchar introspection_xml[] =
+ " <node>"
+ " <interface name='org.tizen.sticker_service'>"
+ " <method name='sticker_service_register'>"
+ " </method>"
+
+ " <method name='insert_sticker_info'>"
+ " <arg type='a{iv}' name='sticker_info' direction='in'/>"
+ " <arg type='a(s)' name='keyword_list' direction='in'/>"
+ " <arg type='i' name='record_id' direction='out'/>"
+ " </method>"
+
+ " <method name='update_sticker_info_by_json'>"
+ " <arg type='s' name='app_id' direction='in'/>"
+ " <arg type='s' name='json_path' direction='in'/>"
+ " </method>"
+
+ " <method name='delete_sticker_info'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " </method>"
+
+ " <method name='update_sticker_type'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='i' name='type' direction='in'/>"
+ " </method>"
+
+ " <method name='update_sticker_uri'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='s' name='app_id' direction='in'/>"
+ " <arg type='i' name='type' direction='in'/>"
+ " <arg type='s' name='uri' direction='in'/>"
+ " </method>"
+
+ " <method name='update_sticker_thumbnail'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='s' name='thumbnail' direction='in'/>"
+ " </method>"
+
+ " <method name='update_sticker_description'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='s' name='description' direction='in'/>"
+ " </method>"
+
+ " <method name='update_sticker_group'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='s' name='group' direction='in'/>"
+ " </method>"
+
+ " <method name='update_sticker_keyword'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='a(s)' name='keyword' direction='in'/>"
+ " </method>"
+
+ " <method name='get_sticker_info'>"
+ " <arg type='i' name='record_id' direction='in'/>"
+ " <arg type='a{iv}' name='sticker_info' direction='out'/>"
+ " <arg type='a(s)' name='keyword_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_group_list'>"
+ " <arg type='a(s)' name='group_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_keyword_list'>"
+ " <arg type='a(s)' name='keyword_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_sticker_count'>"
+ " <arg type='s' name='app_id' direction='in'/>"
+ " <arg type='i' name='count' direction='out'/>"
+ " </method>"
+
+ " <method name='get_all_sticker_info'>"
+ " <arg type='i' name='offset' direction='in'/>"
+ " <arg type='i' name='count' direction='in'/>"
+ " <arg type='a(i)' name='id_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_sticker_info_by_appid'>"
+ " <arg type='s' name='app_id' direction='in'/>"
+ " <arg type='i' name='offset' direction='in'/>"
+ " <arg type='i' name='count' direction='in'/>"
+ " <arg type='a(i)' name='id_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_sticker_info_by_type'>"
+ " <arg type='i' name='type' direction='in'/>"
+ " <arg type='i' name='offset' direction='in'/>"
+ " <arg type='i' name='count' direction='in'/>"
+ " <arg type='a(i)' name='id_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_sticker_info_by_group'>"
+ " <arg type='s' name='group' direction='in'/>"
+ " <arg type='i' name='offset' direction='in'/>"
+ " <arg type='i' name='count' direction='in'/>"
+ " <arg type='a(i)' name='id_list' direction='out'/>"
+ " </method>"
+
+ " <method name='get_sticker_info_by_keyword'>"
+ " <arg type='s' name='keyword' direction='in'/>"
+ " <arg type='i' name='offset' direction='in'/>"
+ " <arg type='i' name='count' direction='in'/>"
+ " <arg type='a(i)' name='id_list' direction='out'/>"
+ " </method>"
+ " </interface>"
+ " </node>";
+
+ return stickerd_server_register_dbus_interface(introspection_xml, _sticker_interface_vtable);
+}
+
+int stickerd_dbus_init(void)
+{
+ int ret;
+
+ ret = stickerd_register_dbus_interface();
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to register dbus interface : %d", ret);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return STICKERD_SERVER_ERROR_NONE;
+}
+
+static int _check_file_exist(const char *app_id, const char *path)
+{
+ int ret = 0;
+ package_info_h package_info = NULL;
+ char *app_path = NULL;
+ char *file_path = NULL;
+
+ if (access(path, F_OK) == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ ret = package_info_create(app_id, &package_info);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = package_info_get_root_path(package_info, &app_path);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ ret = -1;
+ goto cleanup;
+ }
+
+ int path_len = strlen(app_path) + strlen(path) + 2;
+ file_path = (char *)calloc(path_len, sizeof(char));
+ if (!file_path) {
+ LOGE("Failed to alloc memory");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if(path[0] == '/')
+ snprintf(file_path, path_len, "%s%s",app_path, path);
+ else
+ snprintf(file_path, path_len, "%s%s%s",app_path, "/", path);
+
+ if (access(file_path, F_OK) != 0) {
+ LOGE("%s does not exist", file_path);
+ ret = -1;
+ } else
+ ret = 0;
+
+cleanup:
+ if (package_info)
+ package_info_destroy(package_info);
+
+ if (app_path) {
+ free(app_path);
+ app_path = NULL;
+ }
+
+ if (file_path) {
+ free(file_path);
+ file_path = NULL;
+ }
+
+ return ret;
+}
+
+static int _mkdirs(const char *path, mode_t mode)
+{
+ int len = 0;
+ char prev_path[2048];
+ const char *tmp = path;
+
+ if (!path || strlen(path) > 2048)
+ return -1;
+
+ memset(prev_path, '\0', 2048);
+ while ((tmp = strchr(tmp, '/')) != NULL) {
+ len = tmp - path;
+ tmp++;
+
+ if (len == 0)
+ continue;
+
+ strncpy(prev_path, path, len);
+ prev_path[len] = 0x00;
+
+ if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory create error : %s", error_buffer);
+ return -1;
+ }
+ }
+
+ if (mkdir(prev_path, mode) == -1 && errno != EEXIST) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory create error : %s", error_buffer);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int _file_copy(const char *src, const char *dest)
+{
+ int ret = 0;
+ int fd = -1, n_fd = -1;
+ char buf[4096];
+ int tmp_err = 0;
+ int size;
+
+ memset(buf, '\0', 4096);
+ fd = open(src, O_RDONLY);
+ n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
+
+ if (fd == -1 || n_fd == -1) {
+ tmp_err = errno;
+ ret = -1;
+ goto cleanup;
+ }
+
+ while((size = read(fd, buf, 4096))) {
+ if (size == -1) {
+ if(errno == EINTR)
+ continue;
+
+ tmp_err = errno;
+ ret = -1;
+ goto cleanup;
+ }
+
+ while(write(n_fd, buf, size) == -1) {
+ if(errno == EINTR) {
+ continue;
+ } else {
+ tmp_err = errno;
+ goto cleanup;
+ }
+ }
+ }
+
+cleanup:
+ if (fd != -1)
+ close(fd);
+
+ if (n_fd != -1)
+ close(n_fd);
+
+ errno = tmp_err;
+ return ret;
+}
+
+static char* _convert_sticker_uri(const char *uri, const char *appid)
+{
+ int ret;
+ int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(uri) + 3;
+ char * new_path = (char *)calloc(len, sizeof(char));
+ if (new_path == NULL) {
+ LOGE("Failed to alloc memory");
+ return NULL;
+ }
+
+ if (uri[0] == '/')
+ snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, uri);
+ else
+ snprintf(new_path, len, "%s/%s/%s",STICKER_DIRECTORY, appid, uri);
+
+ if (access(new_path, F_OK) == 0) {
+ LOGE("sticker file already exists");
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = _mkdirs(new_path, 0755);
+ if (ret != 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory create error : %s", error_buffer);
+ goto cleanup;
+ }
+
+ ret = _file_copy(uri, new_path);
+ if (ret != 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("failed to copy sticker file : %s", error_buffer);
+ }
+
+cleanup:
+ if (ret == 0) {
+ return new_path;
+ } else {
+ free(new_path);
+ new_path = NULL;
+ return NULL;
+ }
+}
+
+int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id = 0;
+ STICKER_DAT_TYPE key;
+ sticker_info_db *sticker_info = NULL;
+ GVariant *value = NULL;
+ GVariantIter *info_iter = NULL;
+ GVariantIter *keyword_iter = NULL;
+ char *keyword;
+
+ g_variant_get(parameters, "(a{iv}a(s))", &info_iter, &keyword_iter);
+ if (!info_iter || !keyword_iter) {
+ LOGD("failed to get iter");
+ ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
+
+ if (!sticker_info) {
+ ret = STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
+ goto cleanup;
+ }
+
+ while (g_variant_iter_loop (info_iter, "{iv}", &key, &value)) {
+ switch(key) {
+ case STICKER_DATA_TYPE_APP_ID:
+ sticker_info->app_id = (char *) g_variant_get_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_URI_TYPE:
+ sticker_info->type = g_variant_get_int32(value);
+ break;
+ case STICKER_DATA_TYPE_URI:
+ sticker_info->uri = (char *) g_variant_get_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_THUMBNAIL:
+ sticker_info->thumbnail = (char *) g_variant_get_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_DESCRIPTION:
+ sticker_info->description = (char *) g_variant_get_string(value, NULL);
+ break;
+ case STICKER_DATA_TYPE_GROUP:
+ sticker_info->group = (char *) g_variant_get_string(value, NULL);
+ break;
+ default:
+ break;
+ }
+ }
+
+ while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
+ sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
+ }
+
+ if (sticker_info->type == 1) {
+ if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
+ sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
+ if (!sticker_info->uri) {
+ LOGE("failed to copy sticker file");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+ } else {
+ LOGE("sticker file does not exist");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+ }
+
+ ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to insert sticker info");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ *reply_body = g_variant_new("(i)", record_id);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+cleanup:
+ if (value)
+ g_variant_unref(value);
+
+ if (info_iter)
+ g_variant_iter_free(info_iter);
+
+ if (keyword_iter)
+ g_variant_iter_free(keyword_iter);
+
+ if (sticker_info) {
+ free(sticker_info);
+ sticker_info = NULL;
+ }
+
+ return ret;
+}
+
+static char* _get_string_from_object(JsonObject *object, const char *key)
+{
+ if (json_object_has_member(object, key) == false)
+ return NULL;
+
+ const char *str = json_object_get_string_member(object, key);
+ if (str != NULL)
+ return strdup(str);
+ else
+ return NULL;
+}
+
+static int _get_int_from_object(JsonObject *object, const char *key)
+{
+ if (json_object_has_member(object, key) == false)
+ return -1;
+
+ int type = json_object_get_int_member(object, key);
+
+ return type;
+}
+
+int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender)
+{
+ int ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ int record_id;
+ sticker_info_db *sticker_info = NULL;
+ char *app_id = NULL;
+ char *json_path = NULL;
+ JsonParser* parser = NULL;
+ GError* err_msg = NULL;
+ GVariant *body = NULL;
+ char *cmd = "send_insert_result";
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(&s&s)", &app_id, &json_path);
+
+ if (!app_id || !json_path) {
+ LOGE("failed to get parameter");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ SECURE_LOGD("app_id: %s, json path: %s", app_id, json_path);
+
+ parser = json_parser_new();
+ json_parser_load_from_file(parser, json_path, &err_msg);
+ if (err_msg) {
+ LOGE("failed to load json file. error message: %s", err_msg->message);
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ JsonNode *root = json_parser_get_root(parser);
+ if (root == NULL) {
+ LOGE("failed to get root");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ JsonObject *root_obj = json_node_get_object(root);
+ if (root_obj == NULL) {
+ LOGE("failed to get object");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
+ if (sticker_arr == NULL) {
+ LOGE("failed to get array member");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ goto cleanup;
+ }
+
+ int arr_len = json_array_get_length(sticker_arr);
+ for (int i = 0; i < arr_len; i++) {
+ JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
+ if (info_object != NULL) {
+ sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
+ if (!sticker_info) {
+ LOGE("Failed to alloc memory");
+ continue;
+ }
+
+ sticker_info->app_id = app_id;
+ sticker_info->type = _get_int_from_object(info_object, "type");
+ if (sticker_info->type < 1)
+ goto free_memory;
+
+ sticker_info->uri = _get_string_from_object(info_object, "uri");
+ if (!sticker_info->uri)
+ goto free_memory;
+
+ if (sticker_info->type == 1) {
+ if (_check_file_exist(sticker_info->app_id, sticker_info->uri) == 0) {
+ sticker_info->uri = _convert_sticker_uri(sticker_info->uri, sticker_info->app_id);
+ if (!sticker_info->uri)
+ goto free_memory;
+ }
+ }
+
+ sticker_info->group = _get_string_from_object(info_object, "group");
+ if (!sticker_info->group)
+ goto free_memory;
+
+ sticker_info->thumbnail = _get_string_from_object(info_object, "thumbnail");
+ if (!sticker_info->thumbnail)
+ goto free_memory;
+
+ sticker_info->description = _get_string_from_object(info_object, "description");
+
+ JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
+ int keyword_arr_len = json_array_get_length(keyword_arr);
+ if (keyword_arr_len < 1)
+ goto free_memory;
+
+ for (int j = 0; j < keyword_arr_len; j++) {
+ sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)json_array_get_string_element(keyword_arr, j)));
+ }
+
+ ret = stickerd_db_insert_sticker_info(&record_id, sticker_info);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to insert sticker info");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+free_memory:
+ free(sticker_info);
+ sticker_info = NULL;
+ }
+ }
+
+cleanup:
+ if (err_msg)
+ g_error_free(err_msg);
+ if (parser)
+ g_object_unref(parser);
+
+ body = g_variant_new("(i)", ret);
+
+ ret = stickerd_send_dbus_message(body, sender, cmd, STICKER_CLIENT_LIB_PROVIDER);
+ if (ret != STICKERD_SERVER_ERROR_NONE)
+ LOGE("Failed to send insert result to client");
+
+ if(body)
+ g_variant_unref(body);
+
+ return ret;
+}
+
+int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(i)", &record_id);
+
+ ret = stickerd_db_delete_sticker_info(record_id);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to delete sticker info");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ int type;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(ii)", &record_id, &type);
+
+ ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_TYPE, &type);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to update sticker type");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ int type;
+ char *app_id;
+ char *uri;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(i&si&s)", &record_id, &app_id, &type, &uri);
+
+ if (type == 1) {
+ if (_check_file_exist(app_id, uri) == 0) {
+ uri = _convert_sticker_uri(uri, app_id);
+ if (!uri) {
+ LOGE("failed to copy sticker file");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+ }
+ }
+
+ ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_URI, (void *)uri);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to update sticker uri");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ char *thumbnail;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(i&s)", &record_id, &thumbnail);
+
+ ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_THUMBNAIL, (void *)thumbnail);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to update sticker thumbnail");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ char *description;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(i&s)", &record_id, &description);
+
+ ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_DESCRIPTION, (void *)description);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to update sticker description");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ char *group;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(i&s)", &record_id, &group);
+
+ ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_GROUP, (void *)group);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to update sticker group");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ GVariantIter *keyword_iter = NULL;
+ char *keyword = NULL;
+ GList *keyword_list = NULL;
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ g_variant_get(parameters, "(ia(s))", &record_id, &keyword_iter);
+
+ if (!keyword_iter) {
+ LOGD("failed to get iter");
+ return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
+ }
+
+ while (g_variant_iter_loop (keyword_iter, "(s)", &keyword)) {
+ keyword_list = g_list_append(keyword_list, strdup((const char *)keyword));
+ }
+
+ g_variant_iter_free(keyword_iter);
+
+ ret = stickerd_db_update_sticker_info(record_id, STICKER_DB_STICKER_KEYWORD, (void *)keyword_list);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to update sticker keyword");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+static void _set_keyword_builder(char *keyword, GVariantBuilder *keyword_builder)
+{
+ if (!keyword) {
+ LOGE("keyword doesn't exist");
+ return;
+ }
+
+ g_variant_builder_add(keyword_builder, "(s)", strdup((const char *)keyword));
+}
+
+int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int record_id;
+ GVariantBuilder *info_builder;
+ GVariantBuilder *keyword_builder;
+
+ g_variant_get(parameters, "(i)", &record_id);
+ sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
+
+ if (!sticker_info)
+ return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
+
+ ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get sticker info");
+ free(sticker_info);
+ sticker_info = NULL;
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
+
+ keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+ g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
+
+ *reply_body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
+ g_variant_builder_unref(info_builder);
+ g_variant_builder_unref(keyword_builder);
+
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ free(sticker_info);
+ sticker_info = NULL;
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ free(sticker_info);
+ sticker_info = NULL;
+ return ret;
+}
+
+int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ GVariantBuilder *builder = NULL;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+ ret = stickerd_db_get_group_list(builder);
+
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get sticker group list");
+ g_variant_builder_unref(builder);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ *reply_body = g_variant_new("(a(s))", builder);
+ g_variant_builder_unref(builder);
+
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ GVariantBuilder *builder = NULL;
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+ ret = stickerd_db_get_keyword_list(builder);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get sticker keyword list");
+ g_variant_builder_unref(builder);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ *reply_body = g_variant_new("(a(s))", builder);
+ g_variant_builder_unref(builder);
+
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int count;
+ char *app_id = NULL;
+
+ g_variant_get(parameters, "(&s)", &app_id);
+
+ ret = stickerd_db_get_sticker_count(&count, app_id);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get sticker count");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ *reply_body = g_variant_new("(i)", count);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ return ret;
+}
+
+#if 0
+// Send the sticker information by asynchronous communication.
+static int send_sticker_info_async(int record_id, sticker_info_db_type type, const char *sender)
+{
+ int ret;
+ char *cmd = NULL;
+
+ sticker_info_db *sticker_info = (sticker_info_db *)calloc(1, sizeof(sticker_info_db));
+
+ if (!sticker_info)
+ return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
+
+ ret = stickerd_db_get_sticker_info_by_record_id(record_id, sticker_info);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get sticker info");
+ free(sticker_info);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ switch (type) {
+ case STICKER_DB_STICKER_ALL:
+ cmd = "send_all_sticker_info";
+ break;
+ case STICKER_DB_STICKER_APPID:
+ cmd = "send_sticker_info_by_appid";
+ break;
+ case STICKER_DB_STICKER_TYPE:
+ cmd = "send_sticker_info_by_type";
+ break;
+ case STICKER_DB_STICKER_GROUP:
+ cmd = "send_sticker_info_by_goup";
+ break;
+ case STICKER_DB_STICKER_KEYWORD:
+ cmd = "send_sticker_info_by_keyword";
+ break;
+ default:
+ cmd = "";
+ break;
+ }
+
+ GVariantBuilder *info_builder;
+ GVariantBuilder *keyword_builder;
+
+ info_builder = g_variant_builder_new(G_VARIANT_TYPE("a{iv}"));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_INFO_ID, g_variant_new_int32(record_id));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_APP_ID, g_variant_new_string((const gchar *)sticker_info->app_id));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI_TYPE, g_variant_new_int32(sticker_info->type));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_URI, g_variant_new_string((const gchar *)sticker_info->uri));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_THUMBNAIL, g_variant_new_string((const gchar *)sticker_info->thumbnail));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DESCRIPTION, g_variant_new_string((const gchar *)sticker_info->description));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_GROUP, g_variant_new_string((const gchar *)sticker_info->group));
+ g_variant_builder_add(info_builder, "{iv}", STICKER_DATA_TYPE_DATE, g_variant_new_string((const gchar *)sticker_info->date));
+
+ keyword_builder = g_variant_builder_new(G_VARIANT_TYPE("a(s)"));
+ g_list_foreach(sticker_info->keyword, (GFunc) _set_keyword_builder, keyword_builder);
+
+ GVariant *body = g_variant_new("(a{iv}a(s))", info_builder, keyword_builder);
+ g_variant_builder_unref(info_builder);
+ g_variant_builder_unref(keyword_builder);
+
+ ret = stickerd_send_dbus_message(body, sender, cmd);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to send sticker info to client");
+ free(sticker_info);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ free(sticker_info);
+ return ret;
+}
+#endif
+
+static void _set_id_builder(char *id, GVariantBuilder *id_builder)
+{
+ if (!id) {
+ LOGE("id doesn't exist");
+ return;
+ }
+
+ g_variant_builder_add(id_builder, "(i)", atoi(id));
+}
+
+int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ int offset, count;
+ GList *id_list = NULL;
+ GVariantBuilder *id_builder = NULL;
+
+ g_variant_get(parameters, "(ii)", &offset, &count);
+
+ ret = stickerd_db_get_record_id(STICKER_DB_STICKER_ALL, &id_list, NULL, offset, count);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get all sticker id");
+ if(id_list)
+ g_list_free_full(id_list, free);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
+ g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
+
+ *reply_body = g_variant_new("(a(i))", id_builder);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ if (id_list)
+ g_list_free_full(id_list, free);
+
+ if (id_builder)
+ g_variant_builder_unref(id_builder);
+
+ return ret;
+}
+
+int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ GList *id_list = NULL;
+ char *app_id = NULL;
+ int offset, count;
+ GVariantBuilder *id_builder = NULL;
+
+ g_variant_get(parameters, "(&sii)", &app_id, &offset, &count);
+
+ ret = stickerd_db_get_record_id(STICKER_DB_STICKER_APPID, &id_list, (void *)app_id, offset, count);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get all sticker id");
+ if(id_list)
+ g_list_free_full(id_list, free);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
+ g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
+
+ *reply_body = g_variant_new("(a(i))", id_builder);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ if (id_list)
+ g_list_free_full(id_list, free);
+
+ if (id_builder)
+ g_variant_builder_unref(id_builder);
+
+ return ret;
+}
+
+int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ GList *id_list = NULL;
+ int type, offset, count;
+ GVariantBuilder *id_builder = NULL;
+
+ g_variant_get(parameters, "(iii)", &type, &offset, &count);
+
+ ret = stickerd_db_get_record_id(STICKER_DB_STICKER_TYPE, &id_list, &type, offset, count);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get all sticker id");
+ if(id_list)
+ g_list_free_full(id_list, free);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
+ g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
+
+ *reply_body = g_variant_new("(a(i))", id_builder);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ if (id_list)
+ g_list_free_full(id_list, free);
+
+ if (id_builder)
+ g_variant_builder_unref(id_builder);
+
+ return ret;
+}
+
+int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ GList *id_list = NULL;
+ char *group = NULL;
+ int offset, count;
+ GVariantBuilder *id_builder = NULL;
+
+ g_variant_get(parameters, "(&sii)", &group, &offset, &count);
+
+ ret = stickerd_db_get_record_id(STICKER_DB_STICKER_GROUP, &id_list, (void *)group, offset, count);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get all sticker id");
+ if(id_list)
+ g_list_free_full(id_list, free);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
+ g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
+
+ *reply_body = g_variant_new("(a(i))", id_builder);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ if (id_list)
+ g_list_free_full(id_list, free);
+
+ if (id_builder)
+ g_variant_builder_unref(id_builder);
+
+ return ret;
+}
+
+int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body)
+{
+ int ret;
+ GList *id_list = NULL;
+ char *keyword = NULL;
+ int offset, count;
+ GVariantBuilder *id_builder = NULL;
+
+ g_variant_get(parameters, "(&sii)", &keyword, &offset, &count);
+
+ ret = stickerd_db_get_record_id(STICKER_DB_STICKER_KEYWORD, &id_list, (void *)keyword, offset, count);
+ if (ret != STICKERD_SERVER_ERROR_NONE) {
+ LOGE("Failed to get all sticker id");
+ if(id_list)
+ g_list_free_full(id_list, free);
+ return STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ id_builder = g_variant_builder_new(G_VARIANT_TYPE("a(i)"));
+ g_list_foreach(id_list, (GFunc) _set_id_builder, id_builder);
+
+ *reply_body = g_variant_new("(a(i))", id_builder);
+ if (*reply_body == NULL) {
+ LOGE("Failed to create reply_body");
+ ret = STICKERD_SERVER_ERROR_OPERATION_FAILED;
+ }
+
+ if (id_list)
+ g_list_free_full(id_list, free);
+
+ if (id_builder)
+ g_variant_builder_unref(id_builder);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKERD_DATA_MANAGER_H__
+#define __TIZEN_UIX_STICKERD_DATA_MANAGER_H__
+
+#include <gio/gio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int stickerd_dbus_init(void);
+int stickerd_register_dbus_interface(void);
+int stickerd_insert_sticker_info(GVariant *parameters, GVariant **reply_body);
+int stickerd_insert_sticker_info_by_json(GVariant *parameters, GVariant **reply_body, const char *sender);
+int stickerd_del_sticker_info(GVariant *parameters, GVariant **reply_body);
+int stickerd_update_sticker_type(GVariant *parameters, GVariant **reply_body);
+int stickerd_update_sticker_uri(GVariant *parameters, GVariant **reply_body);
+int stickerd_update_sticker_thumbnail(GVariant *parameters, GVariant **reply_body);
+int stickerd_update_sticker_description(GVariant *parameters, GVariant **reply_body);
+int stickerd_update_sticker_group(GVariant *parameters, GVariant **reply_body);
+int stickerd_update_sticker_keyword(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_sticker_info(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_group_list(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_keyword_list(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_sticker_count(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_all_sticker_info(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_sticker_info_by_app_id(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_sticker_info_by_type(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_sticker_info_by_group(GVariant *parameters, GVariant **reply_body);
+int stickerd_get_sticker_info_by_keyword(GVariant *parameters, GVariant **reply_body);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKERD_DATA_MANAGER_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <unistd.h>
+#include <string.h>
+#include <dlog.h>
+#include <sqlite3.h>
+
+#include "stickerd_db_manager.h"
+#include "stickerd_error.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKERD_DB_MANAGER"
+
+/*
+ * Table Information
+ *
+ * sticker_info
+ * +-----------------+--------+------+------+-----------+-------------+------------+------+
+ * | INT | TEXT | INT | TEXT | TEXT | TEXT | TEXT | TEXT |
+ * +-----------------+--------+------+------+-----------+-------------+------------+------+
+ * | sticker_info_id | app_id | type | uri | thumbnail | description | group_name | date |
+ * +-----------------+--------+------+------+-----------+-------------+------------+------+
+ *
+ * sticker_keyword_info
+ * +------------+-----------------+---------+
+ * | INT | INT | TEXT |
+ * +------------+-----------------+---------+
+ * | keyword_id | sticker_info_id | keyword |
+ * +------------+-----------------+---------+
+ *
+ */
+
+#define STICKER_DB_PATH tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db")
+#define STICKER_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_info(sticker_info_id INTEGER PRIMARY KEY AUTOINCREMENT, app_id TEXT NOT NULL, type INTEGER NOT NULL, uri TEXT NOT NULL, thumbnail TEXT, description TEXT, group_name TEXT NOT NULL, date TEXT NOT NULL);"
+#define STICKER_KEYWORD_INFO_CREATE_TABLE "CREATE TABLE IF NOT EXISTS sticker_keyword_info(keyword_id INTEGER PRIMARY KEY AUTOINCREMENT, sticker_info_id INTEGER, keyword TEXT NOT NULL, FOREIGN KEY (sticker_info_id) REFERENCES sticker_info(sticker_info_id) ON DELETE CASCADE)"
+
+#define STICKER_DB_INSERT_STICKER_INFO "INSERT INTO sticker_info (app_id, type, uri, thumbnail, description, group_name, date) VALUES (?, ?, ?, ?, ?, ?, DateTime('now','localtime'))"
+#define STICKER_DB_INSERT_STICKER_KEYWORD_INFO "INSERT INTO sticker_keyword_info (sticker_info_id, keyword) VALUES (?, ?)"
+
+#define STICKER_DB_DELETE_STICKER_INFO "DELETE FROM sticker_info WHERE sticker_info_id = ?"
+#define STICKER_DB_DELETE_STICKER_KEYWORD_INFO "DELETE FROM sticker_keyword_info WHERE sticker_info_id = ?"
+
+#define STICKER_DB_UPDATE_STICKER_TYPE "UPDATE sticker_info SET type = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
+#define STICKER_DB_UPDATE_STICKER_URI "UPDATE sticker_info SET uri = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
+#define STICKER_DB_UPDATE_STICKER_THUMBNAIL "UPDATE sticker_info SET thumbnail = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
+#define STICKER_DB_UPDATE_STICKER_DESCRIPTION "UPDATE sticker_info SET description = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
+#define STICKER_DB_UPDATE_STICKER_GROUP "UPDATE sticker_info SET group_name = ?, date = DateTime('now','localtime') WHERE sticker_info_id = ?"
+
+#define STICKER_DB_GET_LATEST_RECORD_ID "SELECT sticker_info_id FROM sticker_info ORDER BY sticker_info_id DESC LIMIT 1"
+#define STICKER_DB_GET_STICKER_INFO_BY_RECORD_ID "SELECT * FROM sticker_info WHERE sticker_info_id = ?"
+#define STICKER_DB_GET_KEYWORD_INFO_BY_RECORD_ID "SELECT keyword FROM sticker_keyword_info WHERE sticker_info_id = ?"
+#define STICKER_DB_GET_ALL_GROUP_LIST "SELECT group_name from (SELECT DISTINCT group_name from sticker_info)"
+#define STICKER_DB_GET_ALL_KEYWORD_LIST "SELECT keyword from (SELECT DISTINCT keyword from sticker_keyword_info)"
+#define STICKER_DB_GET_STICKER_COUNT "SELECT count(*) FROM sticker_info WHERE app_id = ?"
+#define STICKER_DB_GET_ALL_RECORD_ID "SELECT sticker_info_id from sticker_info LIMIT ?, ?"
+#define STICKER_DB_GET_RECORD_ID_BY_APP_ID "SELECT sticker_info_id from sticker_info WHERE app_id = ? LIMIT ?, ?"
+#define STICKER_DB_GET_RECORD_ID_BY_TYPE "SELECT sticker_info_id from sticker_info WHERE type = ? LIMIT ?, ?"
+#define STICKER_DB_GET_RECORD_ID_BY_GROUP "SELECT sticker_info_id from sticker_info WHERE group_name = ? LIMIT ?, ?"
+#define STICKER_DB_GET_RECORD_ID_BY_KEYWORD "SELECT sticker_info_id from sticker_keyword_info WHERE keyword = ? LIMIT ?, ?"
+
+typedef enum
+{
+ CMD_UPDATE,
+ CMD_SELECT,
+} command_type;
+
+static gboolean is_corrupted = FALSE;
+
+static const char *_db_get_query(sticker_info_db_type sticker_type, command_type cmd_type)
+{
+ static const char* query = NULL;
+
+ if (cmd_type == CMD_UPDATE) {
+ switch(sticker_type) {
+ case STICKER_DB_STICKER_TYPE:
+ query = STICKER_DB_UPDATE_STICKER_TYPE;
+ break;
+ case STICKER_DB_STICKER_URI:
+ query = STICKER_DB_UPDATE_STICKER_URI;
+ break;
+ case STICKER_DB_STICKER_THUMBNAIL:
+ query = STICKER_DB_UPDATE_STICKER_THUMBNAIL;
+ break;
+ case STICKER_DB_STICKER_DESCRIPTION:
+ query = STICKER_DB_UPDATE_STICKER_DESCRIPTION;
+ break;
+ case STICKER_DB_STICKER_GROUP:
+ query = STICKER_DB_UPDATE_STICKER_GROUP;
+ break;
+ case STICKER_DB_STICKER_KEYWORD:
+ query = STICKER_DB_DELETE_STICKER_KEYWORD_INFO;
+ break;
+ default :
+ query = "";
+ break;
+ }
+ } else if (cmd_type == CMD_SELECT) {
+ switch(sticker_type) {
+ case STICKER_DB_STICKER_ALL:
+ query = STICKER_DB_GET_ALL_RECORD_ID;
+ break;
+ case STICKER_DB_STICKER_APPID:
+ query = STICKER_DB_GET_RECORD_ID_BY_APP_ID;
+ break;
+ case STICKER_DB_STICKER_TYPE:
+ query = STICKER_DB_GET_RECORD_ID_BY_TYPE;
+ break;
+ case STICKER_DB_STICKER_GROUP:
+ query = STICKER_DB_GET_RECORD_ID_BY_GROUP;
+ break;
+ case STICKER_DB_STICKER_KEYWORD:
+ query = STICKER_DB_GET_RECORD_ID_BY_KEYWORD;
+ break;
+ default :
+ query = "";
+ break;
+ }
+ }
+
+ return query;
+}
+
+static int _recover_db(void)
+{
+ int ret = STICKERD_SERVER_ERROR_NONE;
+ sqlite3 *db = NULL;
+ char *err = NULL;
+
+ LOGD("Start to recover sticker db");
+ //Remove sticker database file
+ if (unlink(STICKER_DB_PATH) == -1)
+ LOGE("Failed to remove db file");
+
+ ret = sqlite3_open_v2(STICKER_DB_PATH, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to open db : %s", sqlite3_errmsg(db));
+ if (unlink(STICKER_DB_PATH) == -1)
+ LOGE("Failed to remove db file");
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ goto cleanup;
+ }
+
+ ret = sqlite3_exec(db, STICKER_INFO_CREATE_TABLE, NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to create sticker_info table : %s" , err);
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ goto cleanup;
+ }
+
+ ret = sqlite3_exec(db, STICKER_KEYWORD_INFO_CREATE_TABLE, NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to create sticker_keyword_info table : %s", err);
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ }
+
+ is_corrupted = FALSE;
+
+cleanup:
+ if (err)
+ sqlite3_free(err);
+
+ if (db)
+ sqlite3_close(db);
+
+ return ret;
+}
+
+static int _integrity_check_cb(void *pid, int argc, char **argv, char **notUsed)
+{
+ if (strcmp(argv[0], "ok") != 0) {
+ LOGE("DB integrity check failed : %s", argv[0]);
+ is_corrupted = TRUE;
+ return -1;
+ }
+
+ LOGD("Result integrity : %s", argv[0]);
+ return 0;
+}
+
+int stickerd_db_init(void)
+{
+ int ret = STICKERD_SERVER_ERROR_NONE;
+ sqlite3 *db = NULL;
+ char *err = NULL;
+
+ ret = sqlite3_open_v2(STICKER_DB_PATH, &db, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to open db : %s", sqlite3_errmsg(db));
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ goto cleanup;
+ }
+
+ ret = sqlite3_exec(db, STICKER_INFO_CREATE_TABLE, NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to create sticker_info table : %s" , err);
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ goto cleanup;
+ }
+
+ ret = sqlite3_exec(db, STICKER_KEYWORD_INFO_CREATE_TABLE, NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to create sticker_keyword_info table : %s", err);
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ goto cleanup;
+ }
+
+ ret = sqlite3_exec(db, "PRAGMA journal_mode = WAL", NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to set journal_mode : %s", err);
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ goto cleanup;
+ }
+
+ ret = sqlite3_exec(db, "PRAGMA integrity_check", _integrity_check_cb, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to check integrity : %s", err);
+ ret = STICKERD_SERVER_ERROR_DB_FAILED;
+ }
+
+cleanup:
+ if (err)
+ sqlite3_free(err);
+
+ if (db)
+ sqlite3_close(db);
+
+ if (ret == SQLITE_CORRUPT || ret == SQLITE_NOTADB || is_corrupted)
+ ret = _recover_db();
+
+ return ret;
+}
+
+static sqlite3 *_db_open(void)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ char *err = NULL;
+
+ ret = sqlite3_open(STICKER_DB_PATH, &db);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to open db : %s", sqlite3_errmsg(db));
+ return NULL;
+ }
+
+ ret = sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to turn on foreign keys : %s", err);
+ }
+
+ return db;
+}
+
+int stickerd_db_insert_sticker_info(int *record_id, sticker_info_db *sticker_info)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_STICKER_INFO, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_text(stmt, 1, sticker_info->app_id, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_int(stmt, 2, sticker_info->type);
+ sqlite3_bind_text(stmt, 3, sticker_info->uri, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 4, sticker_info->thumbnail, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 5, sticker_info->description, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 6, sticker_info->group, -1, SQLITE_TRANSIENT);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ } else if (sqlite3_changes(db) == 0) {
+ LOGE("No changes to DB");
+ goto cleanup;
+ }
+
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_GET_LATEST_RECORD_ID, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get sticker id : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ERROR) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ *record_id = 0;
+ goto cleanup;
+ } else {
+ *record_id = sqlite3_column_int(stmt, 0);
+ LOGD("record_id : %d", *record_id);
+ }
+
+ GList *list;
+ for(list = sticker_info->keyword; list != NULL; list=list->next) {
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_STICKER_KEYWORD_INFO, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to insert sticker keyword : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_int(stmt, 1, *record_id);
+ sqlite3_bind_text(stmt, 2, (char *)list->data, -1, SQLITE_TRANSIENT);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ } else if (sqlite3_changes(db) == 0) {
+ LOGE("No changes to DB");
+ goto cleanup;
+ }
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_delete_sticker_info(int record_id)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_DELETE_STICKER_INFO, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to delete sticker information : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_int(stmt, 1, record_id);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ } else if (sqlite3_changes(db) == 0) {
+ LOGE("No changes to DB");
+ goto cleanup;
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_update_sticker_info(int record_id, sticker_info_db_type type, void *data)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ const char* query = _db_get_query(type, CMD_UPDATE);
+ ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to update sticker information : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ if (type == STICKER_DB_STICKER_TYPE) {
+ sqlite3_bind_int(stmt, 1, *(int *)data);
+ } else if (type == STICKER_DB_STICKER_KEYWORD) {
+ sqlite3_bind_int(stmt, 1, record_id);
+ } else {
+ sqlite3_bind_text(stmt, 1, (char *)data, -1, SQLITE_TRANSIENT);
+ }
+
+ if (type != STICKER_DB_STICKER_KEYWORD)
+ sqlite3_bind_int(stmt, 2, record_id);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ }
+
+ if (type == STICKER_DB_STICKER_KEYWORD) {
+ GList *list;
+ for(list = (GList *)data; list != NULL; list=list->next) {
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_INSERT_STICKER_KEYWORD_INFO, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_int(stmt, 1, record_id);
+ sqlite3_bind_text(stmt, 2, (char *)list->data, -1, SQLITE_TRANSIENT);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ } else if (sqlite3_changes(db) == 0) {
+ LOGE("No changes to DB");
+ goto cleanup;
+ }
+ }
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_get_sticker_info_by_record_id(int record_id, sticker_info_db *sticker_info)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_GET_STICKER_INFO_BY_RECORD_ID, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get sticker information : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_int(stmt, 1, record_id);
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ERROR) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ }
+
+ const unsigned char *tmp_app_id = sqlite3_column_text(stmt, 1);
+ if (tmp_app_id) {
+ sticker_info->app_id = strdup((const char *)tmp_app_id);
+ } else {
+ LOGW("invalid record_id : %d", record_id);
+ goto cleanup;
+ }
+
+ sticker_info->type = sqlite3_column_int(stmt, 2);
+
+ const unsigned char *tmp_uri = sqlite3_column_text(stmt, 3);
+ if (tmp_uri)
+ sticker_info->uri = strdup((const char *)tmp_uri);
+
+ const unsigned char *tmp_thumbnail = sqlite3_column_text(stmt, 4);
+ if (tmp_thumbnail)
+ sticker_info->thumbnail = strdup((const char *)tmp_thumbnail);
+
+ const unsigned char *tmp_description = sqlite3_column_text(stmt, 5);
+ if (tmp_description)
+ sticker_info->description = strdup((const char *)tmp_description);
+
+ const unsigned char *tmp_group = sqlite3_column_text(stmt, 6);
+ if (tmp_group)
+ sticker_info->group = strdup((const char *)tmp_group);
+
+ const unsigned char *tmp_date = sqlite3_column_text(stmt, 7);
+ if (tmp_date)
+ sticker_info->date = strdup((const char *)tmp_date);
+
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_GET_KEYWORD_INFO_BY_RECORD_ID, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get sticker keyword : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_int(stmt, 1, record_id);
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const unsigned char *keyword = sqlite3_column_text(stmt, 0);
+ if (keyword)
+ sticker_info->keyword = g_list_append(sticker_info->keyword, strdup((const char *)keyword));
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_get_group_list(GVariantBuilder *builder)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_GET_ALL_GROUP_LIST, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get group list : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const unsigned char *group = sqlite3_column_text(stmt, 0);
+ if (group)
+ g_variant_builder_add(builder, "(s)", strdup((const char *)group));
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_get_keyword_list(GVariantBuilder *builder)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_GET_ALL_KEYWORD_LIST, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get keyword list : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const unsigned char *keyword = sqlite3_column_text(stmt, 0);
+ if (keyword)
+ g_variant_builder_add(builder, "(s)", strdup((const char *)keyword));
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_get_sticker_count(int *count, char *app_id)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ ret = sqlite3_prepare_v2(db, STICKER_DB_GET_STICKER_COUNT, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get sticker count : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
+
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ERROR) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ }
+
+ *count = sqlite3_column_int(stmt, 0);
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
+
+int stickerd_db_get_record_id(sticker_info_db_type type, GList **id_list, void *data, int offset, int count)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = _db_open();
+ if (!db)
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+
+ const char* query = _db_get_query(type, CMD_SELECT);
+ ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("fail to get record id : %s", sqlite3_errmsg(db));
+ goto cleanup;
+ }
+
+ if (type == STICKER_DB_STICKER_TYPE)
+ sqlite3_bind_int(stmt, 1, *(int *)data);
+ else if (type != STICKER_DB_STICKER_ALL)
+ sqlite3_bind_text(stmt, 1, (char *)data, -1, SQLITE_TRANSIENT);
+
+ if (type == STICKER_DB_STICKER_ALL) {
+ sqlite3_bind_int(stmt, 1, offset);
+ sqlite3_bind_int(stmt, 2, count);
+ } else {
+ sqlite3_bind_int(stmt, 2, offset);
+ sqlite3_bind_int(stmt, 3, count);
+ }
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const unsigned char *tmp_id = sqlite3_column_text(stmt, 0);
+ if (tmp_id)
+ *id_list = g_list_append(*id_list, strdup((const char *)tmp_id));
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ return STICKERD_SERVER_ERROR_DB_FAILED;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKERD_DB_MANAGER_H__
+#define __TIZEN_UIX_STICKERD_DB_MANAGER_H__
+
+#include <glib.h>
+#include <tzplatform_config.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ STICKER_DB_STICKER_ALL,
+ STICKER_DB_STICKER_APPID,
+ STICKER_DB_STICKER_TYPE,
+ STICKER_DB_STICKER_URI,
+ STICKER_DB_STICKER_THUMBNAIL,
+ STICKER_DB_STICKER_DESCRIPTION,
+ STICKER_DB_STICKER_GROUP,
+ STICKER_DB_STICKER_KEYWORD,
+} sticker_info_db_type;
+
+typedef struct {
+ char *app_id;
+ int type;
+ char *uri;
+ char *thumbnail;
+ char *description;
+ char *group;
+ GList *keyword;
+ char *date;
+} sticker_info_db;
+
+int stickerd_db_init(void);
+int stickerd_db_insert_sticker_info(int *record_id, sticker_info_db *sticker_info);
+int stickerd_db_delete_sticker_info(int record_id);
+int stickerd_db_update_sticker_info(int record_id, sticker_info_db_type type, void *data);
+int stickerd_db_get_sticker_info_by_record_id(int record_id, sticker_info_db *sticker_info);
+int stickerd_db_get_group_list(GVariantBuilder *builder);
+int stickerd_db_get_keyword_list(GVariantBuilder *builder);
+int stickerd_db_get_sticker_count(int *count, char *app_id);
+int stickerd_db_get_record_id(sticker_info_db_type type, GList **id_list, void *data, int offset, int count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKERD_DB_MANAGER_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <gio/gio.h>
+#include <dlog.h>
+
+#include "stickerd_dbus.h"
+#include "stickerd_error.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKERD_DBUS"
+
+static GDBusConnection *_gdbus_connection;
+
+int stickerd_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler,
+ GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash)
+{
+ GList *sender_list = NULL;
+ const char *bus_name = sender;
+ monitoring_info_s *m_info = NULL;
+ uid_t request_uid = 0;
+ GList *monitoring_list = NULL;
+
+ if (bus_name == NULL)
+ return STICKERD_SERVER_ERROR_IO_ERROR;
+
+ g_variant_get(parameters, "(i)", &request_uid);
+ monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid));
+ sender_list = g_list_find_custom(monitoring_list, bus_name, (GCompareFunc) strcmp);
+
+ if (sender_list == NULL) {
+ LOGD("Add a new sender");
+ m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
+ if (m_info == NULL) {
+ LOGE("Failed to alloc memory");
+ return STICKERD_SERVER_ERROR_IO_ERROR;
+ }
+
+ m_info->bus_name = strdup(bus_name);
+ m_info->uid = request_uid;
+ m_info->watcher_id = g_bus_watch_name_on_connection(
+ _gdbus_connection,
+ bus_name,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ name_appeared_handler,
+ name_vanished_handler,
+ m_info,
+ NULL);
+ if (m_info->watcher_id == 0) {
+ LOGE("Failed to get identifier");
+ free(m_info->bus_name);
+ free(m_info);
+ return STICKERD_SERVER_ERROR_IO_ERROR;
+ }
+
+ monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
+ LOGD("sender: %s, len: %d", sender, g_list_length(monitoring_list));
+ if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == NULL)
+ g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
+ } else {
+ LOGW("Sender(%s) already exist", sender);
+ }
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL) {
+ if (m_info) {
+ if (m_info->bus_name)
+ free(m_info->bus_name);
+ free(m_info);
+ }
+ monitoring_list = g_list_remove(monitoring_list, bus_name);
+ LOGE("Failed to make reply");
+ return STICKERD_SERVER_ERROR_OUT_OF_MEMORY;
+ }
+ return STICKERD_SERVER_ERROR_NONE;
+}
+
+int stickerd_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
+{
+ int result;
+ int own_id, registration_id;
+ GError *error = NULL;
+ GDBusNodeInfo *introspection_data = NULL;
+
+ if (_gdbus_connection == NULL) {
+ _gdbus_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (_gdbus_connection == NULL) {
+ if (error != NULL) {
+ LOGE("g_bus_get_sync error message = %s", error->message);
+ g_error_free(error);
+ }
+ result = STICKERD_SERVER_ERROR_IO_ERROR;
+ goto cleanup;
+ }
+ }
+
+ own_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ STICKER_DBUS_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ NULL,
+ NULL,
+ NULL,
+ NULL, NULL);
+ if (own_id == 0) {
+ LOGE("Failed to register bus name");
+ result = STICKERD_SERVER_ERROR_IO_ERROR;
+ goto cleanup;
+ }
+
+ LOGD("own_id = %d", own_id);
+
+ introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
+ if (introspection_data == NULL) {
+ LOGE("Failed to get GDBusNodeInfo");
+ result = STICKERD_SERVER_ERROR_IO_ERROR;
+ if (error != NULL) {
+ LOGE("g_dbus_node_info_new_for_xml error message = %s", error->message);
+ g_error_free(error);
+ }
+ goto cleanup;
+ }
+
+ registration_id = g_dbus_connection_register_object(_gdbus_connection, STICKER_OBJECT_PATH,
+ introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL);
+ LOGD("registration_id = %d", registration_id);
+ if (registration_id == 0) {
+ LOGE("Failed to register object");
+ result = STICKERD_SERVER_ERROR_IO_ERROR;
+ goto cleanup;
+ }
+
+ return STICKERD_SERVER_ERROR_NONE;
+
+cleanup:
+ if (introspection_data)
+ g_dbus_node_info_unref(introspection_data);
+
+ return result;
+}
+
+int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid)
+{
+ GList *monitoring_list = NULL;
+ GList *del_list = NULL;
+ char *bus_name;
+
+ monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
+ if (monitoring_list == NULL) {
+ LOGE("The key(%d) is not found", uid);
+ return STICKERD_SERVER_ERROR_IO_ERROR;
+ }
+
+ monitoring_list = g_list_first(monitoring_list);
+ del_list = g_list_find_custom(monitoring_list, sender, (GCompareFunc) strcmp);
+
+ if (del_list) {
+ LOGD("Delete sender(%s)", sender);
+ bus_name = g_list_nth_data(del_list, 0);
+ if (bus_name)
+ free(bus_name);
+ monitoring_list = g_list_delete_link(monitoring_list, del_list);
+
+ if (monitoring_list == NULL) {
+ g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
+ } else {
+ monitoring_list = g_list_first(monitoring_list);
+ g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
+ }
+ }
+ return STICKERD_SERVER_ERROR_NONE;
+}
+
+int stickerd_send_dbus_message(GVariant *body, const char *dest, char *cmd, CLIENT_LIB lib)
+{
+ GError *err = NULL;
+ char *interface = NULL;
+
+ if (lib == STICKER_CLIENT_LIB_PROVIDER)
+ interface = STICKER_PROVIDER_INTERFACE_NAME;
+ else if (lib == STICKER_CLIENT_LIB_CONSUMER)
+ interface = STICKER_CONSUMER_INTERFACE_NAME;
+
+ if (g_variant_is_floating(body))
+ g_variant_ref(body);
+
+ if (!g_dbus_connection_emit_signal(_gdbus_connection,
+ dest,
+ STICKER_OBJECT_PATH,
+ interface,
+ cmd,
+ body,
+ &err)) {
+ if (err != NULL) {
+ LOGE("Failed to send dbus message : %s", err->message);
+ g_error_free(err);
+ }
+
+ return STICKERD_SERVER_ERROR_IO_ERROR;
+ }
+
+ LOGD("Send message to client : %s", cmd);
+ return STICKERD_SERVER_ERROR_NONE;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKERD_DBUS_H__
+#define __TIZEN_UIX_STICKERD_DBUS_H__
+
+#include <gio/gio.h>
+#include <stdlib.h>
+#include "sticker_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct monitoring_info {
+ int watcher_id;
+ char *bus_name;
+ uid_t uid;
+} monitoring_info_s;
+
+int stickerd_server_register(GVariant *parameters, GVariant **reply_body, const gchar *sender, GBusNameAppearedCallback name_appeared_handler,
+ GBusNameVanishedCallback name_vanished_handler, GHashTable **monitoring_hash);
+int stickerd_server_unregister(GVariant *parameters, GVariant **reply_body, const gchar *sender, GHashTable **monitoring_hash);
+int stickerd_server_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable);
+int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid);
+int stickerd_send_dbus_message(GVariant *body, const char *dest, char *cmd, CLIENT_LIB lib);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKERD_DBUS_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __TIZEN_UIX_STICKERD_ERROR_H__
+#define __TIZEN_UIX_STICKERD_ERROR_H__
+
+/**
+ * @file sticker_error.h
+ * @brief This file contains sticker error enumeration.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Enumeration for sticker server error.
+ */
+enum stickerd_server_error {
+ STICKERD_SERVER_ERROR_NONE,
+ STICKERD_SERVER_ERROR_IO_ERROR,
+ STICKERD_SERVER_ERROR_INVALID_PARAMETER,
+ STICKERD_SERVER_ERROR_PERMISSION_DENIED,
+ STICKERD_SERVER_ERROR_OUT_OF_MEMORY,
+ STICKERD_SERVER_ERROR_SERVICE_NOT_READY,
+ STICKERD_SERVER_ERROR_OPERATION_FAILED,
+ STICKERD_SERVER_ERROR_DB_FAILED,
+};
+
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_UIX_STICKERD_ERROR_H__ */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dlog.h>
+#include <glib.h>
+#include <sys/signalfd.h>
+#include <signal.h>
+
+#include "stickerd_data_manager.h"
+#include "stickerd_db_manager.h"
+#include "stickerd_error.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKERD_MAIN"
+
+#define MAX_ERROR_BUFFER 256
+
+static GMainLoop *main_loop;
+static GIOChannel *channel = NULL;
+static guint source = 0;
+
+static gboolean signal_handler(GIOChannel *channel, GIOCondition condition, gpointer user_data)
+{
+ struct signalfd_siginfo fd_signal;
+ ssize_t size;
+ int sfd;
+
+ sfd = g_io_channel_unix_get_fd(channel);
+ size = read(sfd, &fd_signal, sizeof(struct signalfd_siginfo));
+ if (size != sizeof(struct signalfd_siginfo)) {
+ LOGE("Failed to read signal");
+ return TRUE;
+ }
+
+ LOGE("sender : %d, signal : %d", fd_signal.ssi_pid, fd_signal.ssi_signo);
+ g_main_loop_quit(main_loop);
+
+ return TRUE;
+}
+
+static void register_signal_handler()
+{
+ sigset_t mask;
+ int sfd;
+ int ret;
+ char error_buffer[MAX_ERROR_BUFFER];
+
+ ret = sigemptyset(&mask);
+ if (ret < 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("sigemptyset(): %s", error_buffer);
+ }
+
+ ret = sigaddset(&mask, SIGTERM);
+ if (ret < 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("sigaddset(): %s", error_buffer);
+ }
+
+ ret = sigprocmask(SIG_BLOCK, &mask, NULL);
+ if (ret < 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("sigprocmask(): %s", error_buffer);
+ }
+
+ sfd = signalfd(-1, &mask, SFD_NONBLOCK);
+ if (sfd < 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("signalfd(): %s", error_buffer);
+ }
+
+ channel = g_io_channel_unix_new(sfd);
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+ source = g_io_add_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_OUT, signal_handler, NULL);
+ LOGD("source : %u", source);
+}
+
+static void unregister_signal_handler()
+{
+ if (source > 0)
+ g_source_remove(source);
+ if (channel)
+ g_io_channel_unref(channel);
+}
+
+int main(int argc, char** argv)
+{
+ int ret;
+ main_loop = g_main_loop_new(NULL, FALSE);
+ if (main_loop == NULL) {
+ LOGE("Failed to create GMainLoop structure");
+ return -1;
+ }
+
+ ret = stickerd_dbus_init();
+ if (ret != STICKERD_SERVER_ERROR_NONE)
+ LOGW("Failed to init dbus");
+
+ ret = stickerd_db_init();
+ if (ret != STICKERD_SERVER_ERROR_NONE)
+ LOGW("Failed to init database");
+
+ register_signal_handler();
+
+ g_main_loop_run(main_loop);
+
+ unregister_signal_handler();
+
+ g_main_loop_unref(main_loop);
+
+ return 0;
+}
--- /dev/null
+pkg_check_modules(parser-pkgs REQUIRED
+ capi-base-common
+ dlog
+ glib-2.0
+ json-glib-1.0
+ pkgmgr-info
+ libtzplatform-config
+ capi-appfw-package-manager
+ sqlite3
+)
+
+SET(SRCS
+ sticker-parser.c
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall" )
+SET(extapi "-fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${extapi}")
+SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed")
+
+## Create Library
+ADD_LIBRARY ("${PROJECT_NAME}-parser" SHARED ${SRCS})
+TARGET_LINK_LIBRARIES("${PROJECT_NAME}-parser" ${parser-pkgs_LDFLAGS} )
+
+INSTALL(TARGETS ${PROJECT_NAME}-parser DESTINATION "/etc/package-manager/parserlib/category")
+INSTALL(TARGETS ${PROJECT_NAME}-parser DESTINATION "/etc/package-manager/parserlib/metadata")
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlog.h>
+#include <glib.h>
+#include <json-glib/json-glib.h>
+#include <pkgmgr-info.h>
+#include <sqlite3.h>
+#include <tzplatform_config.h>
+#include <package_manager.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "STICKER_PARSER"
+
+#define STICKER_DIRECTORY tzplatform_mkpath(TZ_SYS_SHARE, "sticker-data")
+#define UIFW_ID 502
+#define APPFW_ID 301
+#define MAX_ERROR_BUFFER 256
+
+static char error_buffer[MAX_ERROR_BUFFER];
+
+typedef struct metadata {
+ const char *key;
+ const char *value;
+} metadata;
+
+static char* __get_string_from_object(JsonObject *object, const char *key)
+{
+ if (json_object_has_member(object, key) == false)
+ return NULL;
+
+ const char *str = json_object_get_string_member(object, key);
+ if (str != NULL)
+ return strdup(str);
+ else
+ return NULL;
+}
+
+static int __get_int_from_object(JsonObject *object, const char *key)
+{
+ if (json_object_has_member(object, key) == false)
+ return -1;
+
+ int type = json_object_get_int_member(object, key);
+
+ return type;
+}
+
+static sqlite3 *__db_open(const char *path)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ char *err = NULL;
+
+ ret = sqlite3_open(path, &db);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to open db : %s", sqlite3_errmsg(db));
+ return NULL;
+ }
+
+ ret = sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, &err);
+ if (ret != SQLITE_OK) {
+ LOGE("Failed to turn on foreign keys : %s", err);
+ }
+
+ return db;
+}
+
+static int __change_ownership(const char *path, int user, int group)
+{
+ int ret;
+ uid_t uid = (uid_t)user;
+ gid_t gid = (gid_t)group;
+
+ ret = chown(path, uid, gid);
+ if (ret != 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("chown() failed : %s", error_buffer);
+ }
+
+ return ret;
+}
+
+static int __remove_app_path(char *uri, const char *app_path)
+{
+ int n = 0;
+ int k = 0;
+ for (int i = 0; uri[i] != '\0'; i++) {
+ if (uri[i] == app_path[n]) {
+ k = i;
+ while (uri[i] == app_path[n]) {
+ if (app_path[++n] == '\0') {
+ for(; uri[k + n] != '\0'; k++) {
+ uri[k] = uri[k + n];
+ }
+ uri[k] = '\0';
+ return 1;
+ }
+ i++;
+ }
+ n = 0;
+ i--;
+ }
+ }
+ return 0;
+}
+
+static int __mkdirs(const char *path, mode_t mode)
+{
+ int len = 0;
+ char prev_path[2048];
+ const char *tmp = path;
+
+ if (!path || strlen(path) > 2048)
+ return -1;
+
+ memset(prev_path, '\0', 2048);
+ while ((tmp = strchr(tmp, '/')) != NULL) {
+ len = tmp - path;
+ tmp++;
+
+ if (len == 0)
+ continue;
+
+ strncpy(prev_path, path, len);
+ prev_path[len] = 0x00;
+
+ if (mkdir(prev_path, mode) == -1) {
+ if (errno != EEXIST) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory create error : %s", error_buffer);
+ return -1;
+ }
+ } else {
+ if (__change_ownership(prev_path, UIFW_ID, UIFW_ID) != 0)
+ LOGE("failed to change ownership");
+ }
+ }
+
+ if (mkdir(prev_path, mode) == -1) {
+ if (errno != EEXIST) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory create error : %s", error_buffer);
+ return -1;
+ }
+ } else {
+ if (__change_ownership(prev_path, UIFW_ID, UIFW_ID) != 0)
+ LOGE("failed to change ownership");
+ }
+ return 0;
+}
+
+static int __file_copy(const char *src, const char *dest)
+{
+ int ret = 0;
+ int fd = -1, n_fd = -1;
+ char buf[4096];
+ int tmp_err = 0;
+ int size;
+
+ memset(buf, '\0', 4096);
+ fd = open(src, O_RDONLY);
+ n_fd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0755);
+
+ if (fd == -1 || n_fd == -1) {
+ tmp_err = errno;
+ ret = -1;
+ goto cleanup;
+ }
+
+ while((size = read(fd, buf, 4096))) {
+ if (size == -1) {
+ if(errno == EINTR)
+ continue;
+
+ tmp_err = errno;
+ ret = -1;
+ goto cleanup;
+ }
+
+ while(write(n_fd, buf, size) == -1) {
+ if(errno == EINTR) {
+ continue;
+ } else {
+ tmp_err = errno;
+ goto cleanup;
+ }
+ }
+ }
+
+cleanup:
+ if (fd != -1)
+ close(fd);
+
+ if (n_fd != -1)
+ close(n_fd);
+
+ errno = tmp_err;
+ return ret;
+}
+
+static char* __convert_sticker_uri(const char *uri, const char *appid, const char *app_path)
+{
+ int ret;
+ char *rel_path = strdup(uri);
+
+ __remove_app_path(rel_path, app_path);
+ int len = strlen(STICKER_DIRECTORY) + strlen(appid) + strlen(rel_path) + 2;
+ char *new_path = (char *)calloc(len, sizeof(char));
+ if (new_path == NULL) {
+ free(rel_path);
+ rel_path = NULL;
+ return NULL;
+ }
+
+ snprintf(new_path, len, "%s/%s%s",STICKER_DIRECTORY, appid, rel_path);
+
+ if (access(new_path, F_OK) == 0) {
+ LOGE("sticker file already exists");
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = __mkdirs(new_path, 0755);
+ if (ret != 0) {
+ LOGE("directory create error");
+ goto cleanup;
+ }
+
+ if (__file_copy(uri, new_path) == -1) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("failed to copy sticker file : %s", error_buffer);
+ ret = -1;
+ goto cleanup;
+ }
+
+ ret = unlink(uri);
+ if (ret != 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("failed to remove sticker file : %s", error_buffer);
+ }
+
+ if (__change_ownership(new_path, UIFW_ID, UIFW_ID) != 0)
+ LOGE("failed to change ownership");
+
+cleanup:
+ free(rel_path);
+ rel_path = NULL;
+
+ if (ret == 0) {
+ return new_path;
+ } else {
+ free(new_path);
+ new_path = NULL;
+ return NULL;
+ }
+}
+
+static void __insert_sticker_info(const char *app_id, int type, const char *uri, const char *group, const char *thumbnail, const char *description)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+ const char *db_path;
+
+ db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
+ db = __db_open(db_path);
+ if (!db)
+ return;
+
+ ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_info (app_id, type, uri, thumbnail, description, group_name, date) VALUES (?, ?, ?, ?, ?, ?, DateTime('now','localtime'))",-1, &stmt, NULL);
+ if (ret == SQLITE_OK) {
+ sqlite3_bind_text(stmt, 1, app_id, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_int(stmt, 2, type);
+ sqlite3_bind_text(stmt, 3, uri, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 4, thumbnail, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 5, description, -1, SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 6, group, -1, SQLITE_TRANSIENT);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE)
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+
+ if (sqlite3_changes(db) == 0)
+ LOGE("No changes to DB");
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ } else {
+ LOGE("failed to insert sticker information : %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ }
+
+ return;
+}
+
+static void __insert_sticker_keyword_info(const char *keyword)
+{
+ int ret;
+ int record_id;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+ const char *db_path;
+
+ db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
+ db = __db_open(db_path);
+ if (!db)
+ return;
+
+ ret = sqlite3_prepare_v2(db, "SELECT sticker_info_id FROM sticker_info ORDER BY sticker_info_id DESC LIMIT 1", -1, &stmt, NULL);
+ if (ret == SQLITE_OK) {
+ ret = sqlite3_step(stmt);
+ if (ret == SQLITE_ERROR) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ } else {
+ record_id = sqlite3_column_int(stmt, 0);
+
+ sqlite3_finalize(stmt);
+ stmt = NULL;
+
+ ret = sqlite3_prepare_v2(db, "INSERT INTO sticker_keyword_info (sticker_info_id, keyword) VALUES (?, ?)", -1, &stmt, NULL);
+ if (ret == SQLITE_OK) {
+ sqlite3_bind_int(stmt, 1, record_id);
+ sqlite3_bind_text(stmt, 2, keyword, -1, SQLITE_TRANSIENT);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE)
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+
+ if (sqlite3_changes(db) == 0)
+ LOGE("No changes to DB");
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ } else {
+ LOGE("fail to insert sticker keyword : %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ }
+ }
+ } else {
+ LOGE("fail to insert sticker information : %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ }
+
+ return;
+}
+
+static int __get_sticker_info_from_json(const char *appid, const char *file_path, const char *app_path)
+{
+ int ret = 1;
+ JsonParser* parser = NULL;
+ GError* err_msg = NULL;
+ char *uri = NULL;
+ char *group = NULL;
+ char *description = NULL;
+ char *thumbnail = NULL;
+ char *uri_path = NULL;
+
+ parser = json_parser_new();
+ json_parser_load_from_file(parser, file_path, &err_msg);
+ if (err_msg) {
+ LOGE("failed to load json file. error message: %s", err_msg->message);
+ ret = 0;
+ goto cleanup;
+ }
+
+ JsonNode *root = json_parser_get_root(parser);
+ if (root == NULL) {
+ LOGE("failed to get root");
+ ret = 0;
+ goto cleanup;
+ }
+
+ JsonObject *root_obj = json_node_get_object(root);
+ if (root_obj == NULL) {
+ LOGE("failed to get object");
+ ret = 0;
+ goto cleanup;
+ }
+
+ JsonArray *sticker_arr = json_object_get_array_member(root_obj, "sticker");
+ if (sticker_arr == NULL) {
+ LOGE("failed to get array member");
+ ret = 0;
+ goto cleanup;
+ }
+
+ int arr_len = json_array_get_length(sticker_arr);
+ for (int i = 0; i < arr_len; i++) {
+ JsonObject *info_object = json_array_get_object_element(sticker_arr, i);
+ if (info_object != NULL) {
+ int type = __get_int_from_object(info_object, "type");
+ if (type < 1)
+ continue;
+
+ uri = __get_string_from_object(info_object, "uri");
+ if (!uri)
+ goto free_memory;
+
+ group = __get_string_from_object(info_object, "group");
+ if (!group)
+ goto free_memory;
+
+ thumbnail = __get_string_from_object(info_object, "thumbnail");
+ description = __get_string_from_object(info_object, "description");
+
+ JsonArray *keyword_arr = json_object_get_array_member(info_object, "keyword");
+ int keyword_arr_len = json_array_get_length(keyword_arr);
+ if (keyword_arr_len < 1)
+ goto free_memory;
+
+ if (type == 1) {
+ if (access(uri, F_OK) == 0) {
+ char *new_uri = __convert_sticker_uri(uri, appid, app_path);
+ if (!new_uri)
+ goto free_memory;
+ __insert_sticker_info(appid, type, new_uri, group, thumbnail, description);
+
+ if (new_uri) {
+ free(new_uri);
+ new_uri = NULL;
+ }
+ } else {
+ int path_len = strlen(app_path) + strlen(uri) + 2;
+ uri_path = (char *)calloc(path_len, sizeof(char));
+ if (!uri_path) {
+ LOGE("failed to alloc memory");
+ goto free_memory;
+ }
+
+ if (uri[0] == '/')
+ snprintf(uri_path, path_len, "%s%s",app_path, uri);
+ else
+ snprintf(uri_path, path_len, "%s%s%s",app_path, "/", uri);
+
+ if (access(uri_path, F_OK) == 0) {
+ char *new_uri = __convert_sticker_uri(uri_path, appid, app_path);
+ if (!new_uri) {
+ free(uri_path);
+ uri_path = NULL;
+ goto free_memory;
+ }
+ __insert_sticker_info(appid, type, new_uri, group, thumbnail, description);
+
+ free(new_uri);
+ new_uri = NULL;
+
+ free(uri_path);
+ uri_path = NULL;
+ } else {
+ LOGE("%s does not exist", uri_path);
+ free(uri_path);
+ uri_path = NULL;
+ goto free_memory;
+ }
+ }
+ } else {
+ __insert_sticker_info(appid, type, uri, group, thumbnail, description);
+ }
+
+ for (int j = 0; j < keyword_arr_len; j++) {
+ __insert_sticker_keyword_info(json_array_get_string_element(keyword_arr, j));
+ }
+
+free_memory:
+ if (uri) {
+ free(uri);
+ uri = NULL;
+ }
+
+ if (group) {
+ free(group);
+ group = NULL;
+ }
+
+ if (thumbnail) {
+ free(thumbnail);
+ thumbnail = NULL;
+ }
+
+ if (description) {
+ free(description);
+ description = NULL;
+ }
+ }
+ }
+
+cleanup:
+ if (err_msg)
+ g_error_free(err_msg);
+
+ if (parser)
+ g_object_unref(parser);
+
+ return ret;
+}
+
+static void __delete_sticker_info(const char *db_path, int record_id)
+{
+ int ret;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+
+ db = __db_open(db_path);
+ if (!db)
+ return;
+
+ ret = sqlite3_prepare_v2(db, "DELETE FROM sticker_info WHERE sticker_info_id = ?", -1, &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ LOGE("failed to delete sticker information : %s", sqlite3_errmsg(db));
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ goto cleanup;
+ }
+
+ sqlite3_bind_int(stmt, 1, record_id);
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_OK && ret != SQLITE_DONE) {
+ LOGE("sqlite3_step() failed : ret(%d)", ret);
+ goto cleanup;
+ }
+
+ if (sqlite3_changes(db) == 0) {
+ LOGE("No changes to DB");
+ goto cleanup;
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ return;
+
+cleanup:
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ return;
+}
+
+static int __remove_directory(const char *path, int is_error_stop)
+{
+ DIR *dir_ptr = NULL;
+ struct dirent *file = NULL;
+ struct stat buf;
+ char filename[1024];
+
+ memset(filename, '\0', 1024);
+
+ if (__change_ownership(path, APPFW_ID, APPFW_ID) != 0)
+ LOGE("failed to change ownership");
+
+ dir_ptr = opendir(path);
+ if (dir_ptr == NULL)
+ return unlink(path);
+
+ while ((file = readdir(dir_ptr)) != NULL) {
+ if (strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)
+ continue;
+
+ snprintf(filename, strlen(path) + strlen(file->d_name) + 2, "%s/%s", path, file->d_name);
+
+ if (lstat(filename, &buf) == -1)
+ continue;
+
+ if (S_ISDIR(buf.st_mode)) {
+ if (__remove_directory(filename, is_error_stop) == -1 && is_error_stop) {
+ closedir(dir_ptr);
+ return -1;
+ }
+ } else if (S_ISREG(buf.st_mode) || S_ISLNK(buf.st_mode)) {
+ if (unlink(filename) == -1 && is_error_stop) {
+ closedir(dir_ptr);
+ return -1;
+ }
+ }
+ }
+
+ closedir(dir_ptr);
+ return rmdir(path);
+}
+
+EXPORT_API
+int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
+{
+ LOGD("METADATA INSTALL");
+ LOGD("pkgid: %s, appid: %s", pkgid, appid);
+
+ metadata *md = NULL;
+ GList *md_list = NULL;
+ package_info_h package_info = NULL;
+ char *app_path = NULL;
+ char *file_path = NULL;
+ int ret = 0;
+
+ ret = package_info_create(pkgid, &package_info);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ goto cleanup;
+ }
+
+ ret = package_info_get_root_path(package_info, &app_path);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE || app_path == NULL) {
+ LOGE("faild to create package_info. ret: %d", ret);
+ goto cleanup;
+ }
+
+ for(md_list = g_list_first(list); md_list != NULL; md_list = md_list->next) {
+ md = (metadata *)md_list->data;
+ int path_len = strlen(app_path) + strlen((char *)md->value) + 2;
+ file_path = (char *)calloc(path_len, sizeof(char));
+ if (!file_path) {
+ LOGE("failed to alloc memory");
+ continue;
+ }
+
+ if ((char)md->value[0] == '/')
+ snprintf(file_path, path_len, "%s%s",app_path, (char *)md->value);
+ else
+ snprintf(file_path, path_len, "%s%s%s",app_path, "/", (char *)md->value);
+
+ if (__get_sticker_info_from_json(appid, file_path, app_path) == 0)
+ LOGE("failed to get sticker information [path : %s]", file_path);
+
+ free(file_path);
+ file_path = NULL;
+ }
+
+cleanup:
+ if (package_info)
+ package_info_destroy(package_info);
+
+ if (app_path) {
+ free(app_path);
+ app_path = NULL;
+ }
+
+ return 0;
+}
+
+EXPORT_API
+int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
+{
+ LOGD("METADATA UNINSTALL");
+ LOGD("pkgid: %s, appid: %s", pkgid, appid);
+
+ int ret;
+ int del_id;
+ sqlite3 *db = NULL;
+ sqlite3_stmt *stmt = NULL;
+ const char *db_path;
+ GList *id_list = NULL;
+
+ db_path = tzplatform_mkpath(TZ_SYS_DB, ".sticker_info.db");
+ db = __db_open(db_path);
+ if (!db)
+ return 0;
+
+ ret = sqlite3_prepare_v2(db, "SELECT sticker_info_id from sticker_info WHERE app_id = ?", -1, &stmt, NULL);
+ if (ret == SQLITE_OK) {
+ sqlite3_bind_text(stmt, 1, appid, -1, SQLITE_TRANSIENT);
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const unsigned char *record_id = sqlite3_column_text(stmt, 0);
+ if (record_id)
+ id_list = g_list_append(id_list, strdup((const char *)record_id));
+ }
+
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+
+ for(GList *tmp = g_list_first(id_list); tmp != NULL; tmp = tmp->next) {
+ del_id = atoi((const char*)tmp->data);
+ __delete_sticker_info(db_path, del_id);
+ }
+
+ if (id_list)
+ g_list_free_full(id_list, free);
+ } else {
+ LOGE("failed to get sticker id");
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ }
+
+ return 0;
+}
+
+EXPORT_API
+int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
+{
+ LOGD("METADATA UPGRADE");
+ LOGD("pkgid: %s, appid: %s", pkgid, appid);
+
+ PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
+ PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list);
+ return 0;
+}
+
+EXPORT_API
+int PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list)
+{
+ LOGD("STICKER CATEGORY INSTALL");
+ LOGD("pkgid: %s, appid: %s", pkgid, appid);
+
+ int len = strlen(STICKER_DIRECTORY) + strlen(appid) + 2;
+ char *dir_path = (char *)calloc(len, sizeof(char));
+
+ if (dir_path != NULL) {
+ snprintf(dir_path, len, "%s%s%s", STICKER_DIRECTORY, "/", appid);
+ LOGD("directory path : %s", dir_path);
+
+ if (mkdir(dir_path, 0755) == -1 && errno != EEXIST) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory create error : %s", error_buffer);
+ } else {
+ if (__change_ownership(dir_path, UIFW_ID, UIFW_ID) != 0)
+ LOGE("failed to change ownership");
+ }
+
+ free(dir_path);
+ dir_path = NULL;
+ }
+
+ return 0;
+}
+
+EXPORT_API
+int PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list)
+{
+ LOGD("STICKER CATEGORY UNINSTALL");
+ LOGD("pkgid: %s, appid: %s", pkgid, appid);
+
+ int len = strlen(STICKER_DIRECTORY) + strlen(appid) + 2;
+ char * dir_path = (char *)calloc(len, sizeof(char));
+
+ if (dir_path != NULL) {
+ snprintf(dir_path, len, "%s%s%s", STICKER_DIRECTORY, "/", appid);
+ LOGD("directory path : %s", dir_path);
+
+ if (__remove_directory(dir_path, 0) < 0) {
+ strerror_r(errno, error_buffer, MAX_ERROR_BUFFER);
+ LOGE("directory remove error : %s", error_buffer);
+ }
+
+ free(dir_path);
+ dir_path = NULL;
+ }
+
+ return 0;
+}
+
+EXPORT_API
+int PKGMGR_CATEGORY_PARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list)
+{
+ LOGD("STICKER CATEGORY UPGRADE");
+ LOGD("pkgid: %s, appid: %s", pkgid, appid);
+
+ PKGMGR_CATEGORY_PARSER_PLUGIN_UNINSTALL(pkgid, appid, list);
+ PKGMGR_CATEGORY_PARSER_PLUGIN_INSTALL(pkgid, appid, list);
+
+ return 0;
+}
\ No newline at end of file