+/*
+ * 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;
+}