From 16cf5efc99bbd4c4c57aff3d477bf2a71065e2b9 Mon Sep 17 00:00:00 2001 From: hyunho Date: Mon, 28 May 2018 15:37:45 +0900 Subject: [PATCH] Fix get default value bug Change-Id: I239b7c9e0ecf1b8a726d84eae98308964cd1bfec Signed-off-by: hyunho --- parser/CMakeLists.txt | 17 +- parser/complication_parser_plugin.c | 584 ----------------- parser/complication_parser_plugin.cc | 688 +++++++++++++++++++++ parser/complication_parser_plugin_internal.c | 245 -------- parser/complication_parser_plugin_internal.cc | 237 +++++++ parser/complication_parser_plugin_internal.h | 4 +- .../complication_parser_plugin_pkgmgr_interface.c | 81 --- .../complication_parser_plugin_pkgmgr_interface.cc | 72 +++ 8 files changed, 1010 insertions(+), 918 deletions(-) delete mode 100644 parser/complication_parser_plugin.c create mode 100644 parser/complication_parser_plugin.cc delete mode 100644 parser/complication_parser_plugin_internal.c create mode 100644 parser/complication_parser_plugin_internal.cc delete mode 100644 parser/complication_parser_plugin_pkgmgr_interface.c create mode 100644 parser/complication_parser_plugin_pkgmgr_interface.cc diff --git a/parser/CMakeLists.txt b/parser/CMakeLists.txt index c6889a6..249cdd5 100644 --- a/parser/CMakeLists.txt +++ b/parser/CMakeLists.txt @@ -1,4 +1,5 @@ -PROJECT(complication-parser C) +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(complication-parser CXX) INCLUDE(FindPkgConfig) pkg_check_modules(PKGS REQUIRED @@ -11,15 +12,19 @@ pkg_check_modules(PKGS REQUIRED ) FOREACH(FLAGS ${PKGS_CFLAGS}) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}") + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${FLAGS}") ENDFOREACH(FLAGS) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror -Wall -fvisibility=hidden -fPIC") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline -std=c++11") + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2") ADD_LIBRARY(${PROJECT_NAME} SHARED - complication_parser_plugin.c - complication_parser_plugin_internal.c - complication_parser_plugin_pkgmgr_interface.c + complication_parser_plugin.cc + complication_parser_plugin_internal.cc + complication_parser_plugin_pkgmgr_interface.cc ) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../watchface-common/include) diff --git a/parser/complication_parser_plugin.c b/parser/complication_parser_plugin.c deleted file mode 100644 index 1b5c00e..0000000 --- a/parser/complication_parser_plugin.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. - * - * 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 -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include "watchface-complication/include/watchface-complication.h" - -#include "complication_parser_plugin_internal.h" - -struct support_type_tag_map { - char *name; - watchface_complication_type_e tag; -}; - -static struct support_type_tag_map support_type_map[] = { - {"short-text-type", WATCHFACE_COMPLICATION_TYPE_SHORT_TEXT}, - {"long-text-type", WATCHFACE_COMPLICATION_TYPE_LONG_TEXT}, - {"ranged-value-type", WATCHFACE_COMPLICATION_TYPE_RANGED_VALUE}, - {"time-type", WATCHFACE_COMPLICATION_TYPE_TIME}, - {"icon-type", WATCHFACE_COMPLICATION_TYPE_ICON}, - {"image-type", WATCHFACE_COMPLICATION_TYPE_IMAGE} -}; - -static uid_t target_uid; -static bool target_uid_initialized; - -static uid_t _get_target_uid(void) -{ - if (target_uid_initialized) - return target_uid; - - pkgmgr_installer_info_get_target_uid(&target_uid); - - target_uid_initialized = true; - - return target_uid; -} - -int complication_parser_plugin_init(void) -{ - LOGD("complication_parser_plugin_init"); - - target_uid_initialized = false; - - if (check_db(_get_target_uid())) { - complication_parser_plugin_fini(); - LOGE("parser init fail"); - return -1; - } - - return 0; -} - -int complication_parser_plugin_fini(void) -{ - LOGD("complication_parser_plugin_fini"); - - target_uid_initialized = false; - - return 0; -} - -static char *_get_attribute(xmlNode *node, const char *name) -{ - xmlChar *val; - char *attr = NULL; - - val = xmlGetProp(node, (const xmlChar *)name); - if (val) { - attr = strdup((char *)val); - xmlFree(val); - } - - return attr; -} - -static int _get_support_type_tag(xmlNode *node) -{ - int i; - - for (i = 0; i < (sizeof(support_type_map) / sizeof(struct support_type_tag_map)); i++) { - if (!xmlStrcasecmp(node->name, (const xmlChar *)support_type_map[i].name)) - return support_type_map[i].tag; - } - - return 0; -} - -static int _parse_support_type(xmlNode *node, sqlite3 *db, const char *pkgid, - const char *appid, const char *providerid, int period) -{ - int ret; - int idx; - int support_type = 0; - int result = -1; - - xmlNode *tmp; - xmlNode *tmpdata; - sqlite3_stmt *stmt = NULL; - - bundle *default_data = NULL; - bundle_raw *raw = NULL; - int len = 0; - - static const char query[] = - "INSERT INTO complication_provider ( " - "pkgid, appid, provider_id, period, " - "support_type, default_data) " - "VALUES (?, ?, ?, ?, ?, ?)"; - - if (node->children == NULL) - return -1; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare error: %s", sqlite3_errmsg(db)); - goto out; - } - - for (tmp = node->children; tmp; tmp = tmp->next) { - if (tmp->children == NULL - || tmp->children->content == NULL) - continue; - - support_type = _get_support_type_tag(tmp); - if (!support_type) { - LOGE("not supported type"); - goto out; - } - - default_data = bundle_create(); - if (default_data == NULL) { - LOGE("bundle create error"); - goto out; - } - - for (tmpdata = tmp->children; tmpdata; tmpdata = tmpdata->next) { - if (tmpdata->children != NULL - && tmpdata->children->content != NULL) { - - ret = bundle_add_str(default_data, (char *)tmpdata->name, - (char *)tmpdata->children->content); - if (ret != BUNDLE_ERROR_NONE) { - LOGE("bundle add error"); - goto out; - } - } - } - - ret = bundle_encode(default_data, &raw, &len); - if (ret != BUNDLE_ERROR_NONE) { - LOGE("bundle encode error"); - goto out; - } - - idx = 1; - - sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, idx++, appid, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT); - sqlite3_bind_int(stmt, idx++, period); - sqlite3_bind_int(stmt, idx++, support_type); - sqlite3_bind_text(stmt, idx, (char *)raw, -1, SQLITE_TRANSIENT); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - LOGE("step error: %s", sqlite3_errmsg(db)); - goto out; - } - - sqlite3_reset(stmt); - sqlite3_clear_bindings(stmt); - - if (raw) { - free(raw); - raw = NULL; - } - - if (default_data) { - bundle_free(default_data); - default_data = NULL; - } - } - - result = 0; -out: - if (default_data) - bundle_free(default_data); - - if (raw) - free(raw); - - if (stmt) - sqlite3_finalize(stmt); - - return result; -} - -static int _parse_label(xmlNode *node, sqlite3 *db, const char *providerid) -{ - int ret; - int idx; - sqlite3_stmt *stmt = NULL; - xmlChar *lang = NULL; - - static const char query[] = - "INSERT INTO provider_localized_info " - "(provider_id, locale, provider_label) " - "VALUES (?, ?, ?)"; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare error: %s", sqlite3_errmsg(db)); - goto out; - } - - lang = xmlNodeGetLang(node); - - idx = 1; - - sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT); - - if (lang) - sqlite3_bind_text(stmt, idx++, (char *)lang, -1, SQLITE_TRANSIENT); - else - sqlite3_bind_text(stmt, idx++, "No Locale", -1, SQLITE_TRANSIENT); - - sqlite3_bind_text(stmt, idx, (char *)node->children->content, -1, SQLITE_TRANSIENT); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - LOGE("step error: %s", sqlite3_errmsg(db)); - goto out; - } - - ret = 0; -out: - if (stmt) - sqlite3_finalize(stmt); - - if (lang) - xmlFree(lang); - - return ret; -} - -static int _parse_privilege(xmlNode *node, sqlite3 *db, const char *providerid) -{ - int ret; - sqlite3_stmt *stmt = NULL; - xmlNode *tmp; - - static const char query[] = - "INSERT INTO provider_privilege " - "(provider_id, privilege) " - "VALUES (?, ?)"; - - if (node->children == NULL) - return -1; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare error: %s", sqlite3_errmsg(db)); - goto out; - } - - for (tmp = node->children; tmp; tmp = tmp->next) { - if (!xmlStrcasecmp(tmp->name, (const xmlChar *)"privilege")) { - sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, 2, (char *)tmp->children->content, -1, SQLITE_TRANSIENT); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - LOGE("step error: %s", sqlite3_errmsg(db)); - goto out; - } - - sqlite3_reset(stmt); - sqlite3_clear_bindings(stmt); - } - } - - ret = 0; -out: - if (stmt) - sqlite3_finalize(stmt); - - return ret; -} - -static int _parse_setup_appid(sqlite3 *db, const char *providerid, - const char *setup_appid) -{ - int ret; - sqlite3_stmt *stmt = NULL; - - static const char query[] = - "INSERT INTO provider_setup_appid " - "(provider_id, setup_appid) " - "VALUES (?, ?)"; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare error: %s", sqlite3_errmsg(db)); - goto out; - } - - sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT); - sqlite3_bind_text(stmt, 2, setup_appid, -1, SQLITE_TRANSIENT); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - LOGE("step error: %s", sqlite3_errmsg(db)); - goto out; - } - - ret = 0; -out: - if (stmt) - sqlite3_finalize(stmt); - - return ret; -} - -static int _parse_complication(xmlNode *node, sqlite3 *db, const char *pkgid, - const char *appid, const char *providerid, const char *setup_appid) -{ - int period = -1; - - xmlNode *tmp = NULL; - xmlNode *support_type_node = NULL; - - if (node->children == NULL) - return -1; - - for (tmp = node->children; tmp; tmp = tmp->next) { - if (!xmlStrcasecmp(tmp->name, (const xmlChar *)"support-type")) { - if (tmp->children == NULL) - return -1; - - support_type_node = tmp; - } else if (!xmlStrcasecmp(tmp->name, (const xmlChar *)"period")) { - if (tmp->children == NULL - || tmp->children->content == NULL) - return -1; - - period = atoi((char *)tmp->children->content); - if (period < 60) - period = 60; - } else if (!xmlStrcasecmp(tmp->name, (const xmlChar *)"label")) { - if (_parse_label(tmp, db, providerid)) { - LOGE("parse label fail"); - return -1; - } - } else if (!xmlStrcasecmp(tmp->name, (const xmlChar *)"privileges")) { - if (_parse_privilege(tmp, db, providerid)) { - LOGE("parse privilege fail"); - return -1; - } - } - } - - if (!support_type_node) { - LOGE("complication provider doesn't have support-type"); - return -1; - } - - if (setup_appid) { - if (_parse_setup_appid(db, providerid, setup_appid)) { - LOGE("parse setup appid fail"); - return -1; - } - } - - if (_parse_support_type(support_type_node, db, pkgid, - appid, providerid, period)) { - LOGE("parse support type fail"); - return -1; - } - - return 0; -} - -static int _parse_service_application(xmlNode *node, const char *pkgid) -{ - int result = -1; - char *appid; - char *providerid; - char *setup_appid; - xmlNode *tmp; - sqlite3 *db; - - appid = _get_attribute(node, "appid"); - if (appid == NULL) - return -1; - - db = open_db(_get_target_uid()); - if (db == NULL) { - LOGE("failed to open db"); - goto out; - } - - if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) { - LOGE("begin transaction error"); - goto out; - } - - for (tmp = node->children; tmp; tmp = tmp->next) { - if (!xmlStrcasecmp(tmp->name, (const xmlChar *)"complication")) { - providerid = _get_attribute(tmp, "provider-id"); - if (providerid == NULL) { - LOGE("provider-id error"); - - sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); - goto out; - } - - setup_appid = _get_attribute(tmp, "setup-appid"); - - if (_parse_complication(tmp, db, pkgid, appid, - providerid, setup_appid)) { - LOGE("parse complication error"); - - sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); - - free(providerid); - - if (setup_appid) - free(setup_appid); - - goto out; - } - - free(providerid); - - if (setup_appid) - free(setup_appid); - } - } - - if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) { - LOGE("end transaction error"); - goto out; - } - - result = 0; -out: - if (db) - sqlite3_close_v2(db); - - if (appid) - free(appid); - - return result; -} - -int complication_parser_plugin_parse_manifest(xmlDocPtr doc, const char *pkgid) -{ - xmlNode *root; - xmlNode *tmp; - - if (doc == NULL) { - LOGE("invalid parameter"); - return -1; - } - - root = xmlDocGetRootElement(doc); - if (root == NULL) { - LOGE("failed to get root element"); - return -1; - } - - for (tmp = root->children; tmp; tmp = tmp->next) { - if (xmlStrcasecmp(tmp->name, (const xmlChar *)"service-application")) - continue; - - if (_parse_service_application(tmp, pkgid)) { - LOGE("parse failed"); - return -1; - } - } - - return 0; -} - -static int _remove_complication(sqlite3 *db, const char *pkgid) -{ - int ret; - int i; - sqlite3_stmt *stmt = NULL; - - static const char *query[] = { - "DELETE FROM provider_privilege WHERE provider_id IN " - "(SELECT DISTINCT provider_id FROM complication_provider " - "WHERE pkgid=?)", - "DELETE FROM provider_localized_info WHERE provider_id IN " - "(SELECT DISTINCT provider_id FROM complication_provider " - "WHERE pkgid=?)", - "DELETE FROM provider_setup_appid WHERE provider_id IN " - "(SELECT DISTINCT provider_id FROM complication_provider " - "WHERE pkgid=?)", - "DELETE FROM complication_provider WHERE pkgid=?" - }; - - for (i = 0; i < (sizeof(query) / sizeof(*query)); i++) { - ret = sqlite3_prepare_v2(db, query[i], strlen(query[i]), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare error: %s", sqlite3_errmsg(db)); - return -1; - } - - sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT); - - ret = sqlite3_step(stmt); - if (ret != SQLITE_DONE) { - LOGE("step error: %s", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - return -1; - } - - sqlite3_finalize(stmt); - } - - return 0; -} - -int complication_parser_db_remove_complication(const char *pkgid) -{ - int result = -1; - sqlite3 *db; - - db = open_db(_get_target_uid()); - if (db == NULL) - return -1; - - if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) { - LOGE("begin transaction error"); - goto out; - } - - if (_remove_complication(db, pkgid)) { - LOGE("failed to remove complication provider"); - - sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); - goto out; - } - - if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) { - LOGE("begin transaction error"); - goto out; - } - - result = 0; -out: - if (db) - sqlite3_close_v2(db); - - return result; -} diff --git a/parser/complication_parser_plugin.cc b/parser/complication_parser_plugin.cc new file mode 100644 index 0000000..8582858 --- /dev/null +++ b/parser/complication_parser_plugin.cc @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include "watchface-complication/include/watchface-complication-internal.h" +#include "watchface-complication/include/watchface-complication.h" + +#include "complication_parser_plugin_internal.h" + +#define DEFAULT_SHORT_TEXT "default-shorttext" +#define DEFAULT_LONG_TEXT "default-longtext" +#define DEFAULT_ICON "default-icon" +#define DEFAULT_TITLE "default-title" +#define DEFAULT_HOUR "default-hour" +#define DEFAULT_MINUTE "default-minute" +#define DEFAULT_SECOND "default-second" +#define DEFAULT_CURRENT "default-current" +#define DEFAULT_MAX "default-max" +#define DEFAULT_MIN "default-min" +#define DEFAULT_IMAGE "default-image" +#define DEFAULT_EXTRA_DATA "default-extra-data" + +struct support_type_tag_map { + const char* name; + watchface_complication_type_e tag; +}; + +static struct support_type_tag_map __type_map[] = { + {"short-text-type", WATCHFACE_COMPLICATION_TYPE_SHORT_TEXT}, + {"long-text-type", WATCHFACE_COMPLICATION_TYPE_LONG_TEXT}, + {"ranged-value-type", WATCHFACE_COMPLICATION_TYPE_RANGED_VALUE}, + {"time-type", WATCHFACE_COMPLICATION_TYPE_TIME}, + {"icon-type", WATCHFACE_COMPLICATION_TYPE_ICON}, + {"image-type", WATCHFACE_COMPLICATION_TYPE_IMAGE} +}; + +struct xml_to_bundle_key_map { + const char* xml_element; + const char* bundle_key; +}; + +static struct xml_to_bundle_key_map __budle_key_map[] = { + {DEFAULT_SHORT_TEXT, SHORT_TEXT_KEY}, + {DEFAULT_LONG_TEXT, LONG_TEXT_KEY}, + {DEFAULT_ICON, ICON_KEY}, + {DEFAULT_TITLE, TITLE_KEY}, + {DEFAULT_HOUR, TIME_KEY}, + {DEFAULT_MINUTE, TIME_KEY}, + {DEFAULT_SECOND, TIME_KEY}, + {DEFAULT_CURRENT, RANGE_CUR_KEY}, + {DEFAULT_MAX, RANGE_MAX_KEY}, + {DEFAULT_MIN, RANGE_MIN_KEY}, + {DEFAULT_IMAGE, IMAGE_KEY}, + {DEFAULT_EXTRA_DATA, EXTRA_DATA_KEY} +}; + +static uid_t __target_uid; +static bool __target_uid_initialized; + +static uid_t _get_target_uid(void) { + if (__target_uid_initialized) + return __target_uid; + + pkgmgr_installer_info_get_target_uid(&__target_uid); + + __target_uid_initialized = true; + + return __target_uid; +} + +int complication_parser_plugin_init(void) { + LOGD("complication_parser_plugin_init"); + + __target_uid_initialized = false; + + if (check_db(_get_target_uid())) { + complication_parser_plugin_fini(); + LOGE("parser init fail"); + return -1; + } + + return 0; +} + +int complication_parser_plugin_fini(void) { + LOGD("complication_parser_plugin_fini"); + + __target_uid_initialized = false; + + return 0; +} + +static char* _get_attribute(xmlNode* node, const char* name) { + xmlChar* val; + char* attr = NULL; + + val = xmlGetProp(node, (const xmlChar*)name); + if (val) { + attr = strdup((char*)val); + xmlFree(val); + } + + return attr; +} + +static int _get_support_type_tag(xmlNode* node) { + unsigned int i; + + for (i = 0; i < (sizeof(__type_map) / sizeof(struct support_type_tag_map)); i++) { + if (!xmlStrcasecmp(node->name, (const xmlChar*)__type_map[i].name)) + return __type_map[i].tag; + } + + return 0; +} + +static const char* _get_bundle_key(const char* xml_element) { + unsigned int i; + + for (i = 0; i < (sizeof(__budle_key_map) / sizeof(struct xml_to_bundle_key_map)); i++) { + if (strcmp(xml_element, __budle_key_map[i].xml_element) == 0) + return __budle_key_map[i].bundle_key; + } + + return NULL; +} + +static bool _is_valid_element(int type, char* element_name) { + bool is_valid = true; + switch (type) { + case WATCHFACE_COMPLICATION_TYPE_SHORT_TEXT : + if (strcmp(element_name, DEFAULT_TITLE) != 0 && + strcmp(element_name, DEFAULT_SHORT_TEXT) != 0 && + strcmp(element_name, DEFAULT_ICON) != 0 && + strcmp(element_name, DEFAULT_EXTRA_DATA) != 0) { + LOGE("type (%d) do not support (%s)", type, element_name); + is_valid = false; + } + break; + case WATCHFACE_COMPLICATION_TYPE_LONG_TEXT : + if (strcmp(element_name, DEFAULT_TITLE) != 0 && + strcmp(element_name, DEFAULT_LONG_TEXT) != 0 && + strcmp(element_name, DEFAULT_ICON) != 0 && + strcmp(element_name, DEFAULT_EXTRA_DATA) != 0) { + LOGE("type (%d) do not support (%s)", type, element_name); + is_valid = false; + } + break; + case WATCHFACE_COMPLICATION_TYPE_RANGED_VALUE : + if (strcmp(element_name, DEFAULT_TITLE) != 0 && + strcmp(element_name, DEFAULT_SHORT_TEXT) != 0 && + strcmp(element_name, DEFAULT_ICON) != 0 && + strcmp(element_name, DEFAULT_MIN) != 0 && + strcmp(element_name, DEFAULT_MAX) != 0 && + strcmp(element_name, DEFAULT_CURRENT) != 0 && + strcmp(element_name, DEFAULT_EXTRA_DATA) != 0) { + LOGE("type (%d) do not support (%s)", type, element_name); + is_valid = false; + } + break; + case WATCHFACE_COMPLICATION_TYPE_ICON : + if (strcmp(element_name, DEFAULT_ICON) != 0 && + strcmp(element_name, DEFAULT_EXTRA_DATA) != 0) { + LOGE("type (%d) do not support (%s)", type, element_name); + is_valid = false; + } + break; + case WATCHFACE_COMPLICATION_TYPE_IMAGE : + if (strcmp(element_name, DEFAULT_IMAGE) != 0 && + strcmp(element_name, DEFAULT_EXTRA_DATA) != 0) { + LOGE("type (%d) do not support (%s)", type, element_name); + is_valid = false; + } + break; + case WATCHFACE_COMPLICATION_TYPE_TIME : + if (strcmp(element_name, DEFAULT_SHORT_TEXT) != 0 && + strcmp(element_name, DEFAULT_HOUR) != 0 && + strcmp(element_name, DEFAULT_MINUTE) != 0 && + strcmp(element_name, DEFAULT_SECOND) != 0 && + strcmp(element_name, DEFAULT_EXTRA_DATA) != 0) { + LOGE("type (%d) do not support (%s)", type, element_name); + is_valid = false; + } + break; + default : + break; + } + + return is_valid; +} + +static int _parse_support_type(xmlNode* node, sqlite3* db, const char* pkgid, + const char* appid, const char* providerid, int period) { + int ret; + int idx; + int support_type = 0; + int result = -1; + + xmlNode* tmp; + xmlNode* tmpdata; + sqlite3_stmt* stmt = NULL; + + bundle* default_data = NULL; + bundle_raw* raw = NULL; + int len = 0; + const char* bundle_key; + + static const char query[] = + "INSERT INTO complication_provider ( " + "pkgid, appid, provider_id, period, " + "support_type, default_data) " + "VALUES (?, ?, ?, ?, ?, ?)"; + + if (node->children == NULL) + return -1; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + goto out; + } + + for (tmp = node->children; tmp; tmp = tmp->next) { + if (tmp->children == NULL + || tmp->children->content == NULL) + continue; + + support_type = _get_support_type_tag(tmp); + if (!support_type) { + LOGE("not supported type"); + goto out; + } + + default_data = bundle_create(); + if (default_data == NULL) { + LOGE("bundle create error"); + goto out; + } + + for (tmpdata = tmp->children; tmpdata; tmpdata = tmpdata->next) { + if (tmpdata->children != NULL + && tmpdata->children->content != NULL) { + if (!_is_valid_element(support_type, (char*)tmpdata->name)) + goto out; + + bundle_key = _get_bundle_key((const char*)tmpdata->name); + if (bundle_key == NULL) { + LOGE("wrong element name (%s)", (const char*)tmpdata->name); + goto out; + } + + ret = bundle_add_str(default_data, bundle_key, + (char *)tmpdata->children->content); + if (ret != BUNDLE_ERROR_NONE) { + LOGE("bundle add error"); + goto out; + } + } + } + + ret = bundle_encode(default_data, &raw, &len); + if (ret != BUNDLE_ERROR_NONE) { + LOGE("bundle encode error"); + goto out; + } + + idx = 1; + + sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, idx++, appid, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT); + sqlite3_bind_int(stmt, idx++, period); + sqlite3_bind_int(stmt, idx++, support_type); + sqlite3_bind_text(stmt, idx, (char*)raw, -1, SQLITE_TRANSIENT); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + goto out; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + + if (raw) { + free(raw); + raw = NULL; + } + + if (default_data) { + bundle_free(default_data); + default_data = NULL; + } + } + + result = 0; +out: + if (default_data) + bundle_free(default_data); + + if (raw) + free(raw); + + if (stmt) + sqlite3_finalize(stmt); + + return result; +} + +static int _parse_label(xmlNode* node, sqlite3* db, const char* providerid) { + int ret; + int idx; + sqlite3_stmt* stmt = NULL; + xmlChar* lang = NULL; + + static const char query[] = + "INSERT INTO provider_localized_info " + "(provider_id, locale, provider_label) " + "VALUES (?, ?, ?)"; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + goto out; + } + + lang = xmlNodeGetLang(node); + + idx = 1; + + sqlite3_bind_text(stmt, idx++, providerid, -1, SQLITE_TRANSIENT); + + if (lang) + sqlite3_bind_text(stmt, idx++, (char*)lang, -1, SQLITE_TRANSIENT); + else + sqlite3_bind_text(stmt, idx++, "No Locale", -1, SQLITE_TRANSIENT); + + sqlite3_bind_text(stmt, idx, (char*)node->children->content, -1, SQLITE_TRANSIENT); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + goto out; + } + + ret = 0; +out: + if (stmt) + sqlite3_finalize(stmt); + + if (lang) + xmlFree(lang); + + return ret; +} + +static int _parse_privilege(xmlNode* node, sqlite3* db, const char* providerid) { + int ret; + sqlite3_stmt* stmt = NULL; + xmlNode* tmp; + + static const char query[] = + "INSERT INTO provider_privilege " + "(provider_id, privilege) " + "VALUES (?, ?)"; + + if (node->children == NULL) + return -1; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + goto out; + } + + for (tmp = node->children; tmp; tmp = tmp->next) { + if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"privilege")) { + sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 2, (char*)tmp->children->content, -1, SQLITE_TRANSIENT); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + goto out; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + } + } + + ret = 0; +out: + if (stmt) + sqlite3_finalize(stmt); + + return ret; +} + +static int _parse_setup_appid(sqlite3* db, const char* providerid, + const char* setup_appid) { + int ret; + sqlite3_stmt* stmt = NULL; + + static const char query[] = + "INSERT INTO provider_setup_appid " + "(provider_id, setup_appid) " + "VALUES (?, ?)"; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + goto out; + } + + sqlite3_bind_text(stmt, 1, providerid, -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 2, setup_appid, -1, SQLITE_TRANSIENT); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + goto out; + } + + ret = 0; +out: + if (stmt) + sqlite3_finalize(stmt); + + return ret; +} + +static int _parse_complication(xmlNode* node, sqlite3* db, const char* pkgid, + const char* appid, const char* providerid, const char* setup_appid) { + int period = -1; + + xmlNode* tmp = NULL; + xmlNode* support_type_node = NULL; + + if (node->children == NULL) + return -1; + + for (tmp = node->children; tmp; tmp = tmp->next) { + if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"support-type")) { + if (tmp->children == NULL) + return -1; + + support_type_node = tmp; + } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"period")) { + if (tmp->children == NULL + || tmp->children->content == NULL) + return -1; + + period = atoi((char*)tmp->children->content); + if (period < 60) + period = 60; + } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"label")) { + if (_parse_label(tmp, db, providerid)) { + LOGE("parse label fail"); + return -1; + } + } else if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"privileges")) { + if (_parse_privilege(tmp, db, providerid)) { + LOGE("parse privilege fail"); + return -1; + } + } + } + + if (!support_type_node) { + LOGE("complication provider doesn't have support-type"); + return -1; + } + + if (setup_appid) { + if (_parse_setup_appid(db, providerid, setup_appid)) { + LOGE("parse setup appid fail"); + return -1; + } + } + + if (_parse_support_type(support_type_node, db, pkgid, + appid, providerid, period)) { + LOGE("parse support type fail"); + return -1; + } + + return 0; +} + +static int _parse_service_application(xmlNode* node, const char* pkgid) { + int result = -1; + char* appid; + char* providerid; + char* setup_appid; + xmlNode* tmp; + sqlite3* db; + + appid = _get_attribute(node, "appid"); + if (appid == NULL) + return -1; + + db = open_db(_get_target_uid()); + if (db == NULL) { + LOGE("failed to open db"); + goto out; + } + + if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + goto out; + } + + for (tmp = node->children; tmp; tmp = tmp->next) { + if (!xmlStrcasecmp(tmp->name, (const xmlChar*)"complication")) { + providerid = _get_attribute(tmp, "provider-id"); + if (providerid == NULL) { + LOGE("provider-id error"); + + sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); + goto out; + } + + setup_appid = _get_attribute(tmp, "setup-appid"); + + if (_parse_complication(tmp, db, pkgid, appid, + providerid, setup_appid)) { + LOGE("parse complication error"); + + sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); + + free(providerid); + + if (setup_appid) + free(setup_appid); + + goto out; + } + + free(providerid); + + if (setup_appid) + free(setup_appid); + } + } + + if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) { + LOGE("end transaction error"); + goto out; + } + + result = 0; +out: + if (db) + sqlite3_close_v2(db); + + if (appid) + free(appid); + + return result; +} + +int complication_parser_plugin_parse_manifest(xmlDocPtr doc, const char* pkgid) { + xmlNode* root; + xmlNode* tmp; + + if (doc == NULL) { + LOGE("invalid parameter"); + return -1; + } + + root = xmlDocGetRootElement(doc); + if (root == NULL) { + LOGE("failed to get root element"); + return -1; + } + + for (tmp = root->children; tmp; tmp = tmp->next) { + if (xmlStrcasecmp(tmp->name, (const xmlChar*)"service-application")) + continue; + + if (_parse_service_application(tmp, pkgid)) { + LOGE("parse failed"); + return -1; + } + } + + return 0; +} + +static int _remove_complication(sqlite3* db, const char* pkgid) { + int ret; + unsigned int i; + sqlite3_stmt* stmt = NULL; + + static const char* query[] = { + "DELETE FROM provider_privilege WHERE provider_id IN " + "(SELECT DISTINCT provider_id FROM complication_provider " + "WHERE pkgid=?)", + "DELETE FROM provider_localized_info WHERE provider_id IN " + "(SELECT DISTINCT provider_id FROM complication_provider " + "WHERE pkgid=?)", + "DELETE FROM provider_setup_appid WHERE provider_id IN " + "(SELECT DISTINCT provider_id FROM complication_provider " + "WHERE pkgid=?)", + "DELETE FROM complication_provider WHERE pkgid=?" + }; + + for (i = 0; i < (sizeof(query) / sizeof(*query)); i++) { + ret = sqlite3_prepare_v2(db, query[i], strlen(query[i]), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_TRANSIENT); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + return -1; + } + + sqlite3_finalize(stmt); + } + + return 0; +} + +int complication_parser_db_remove_complication(const char* pkgid) { + int result = -1; + sqlite3* db; + + db = open_db(_get_target_uid()); + if (db == NULL) + return -1; + + if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + goto out; + } + + if (_remove_complication(db, pkgid)) { + LOGE("failed to remove complication provider"); + + sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); + goto out; + } + + if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + goto out; + } + + result = 0; +out: + if (db) + sqlite3_close_v2(db); + + return result; +} diff --git a/parser/complication_parser_plugin_internal.c b/parser/complication_parser_plugin_internal.c deleted file mode 100644 index 70ee9cf..0000000 --- a/parser/complication_parser_plugin_internal.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. - * - * 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 -#include -#include - -#include - -#include -#include - -#include "complication_parser_plugin_internal.h" - -#define BUSY_WAITING_USEC 50000 /* 0.05 sec */ -#define BUSY_WAITING_MAX 20 /* wait for max 1 sec */ -#define ROOT_USER 0 -#define GLOBALAPP_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) - -#define CREATE_COMPLICATION_TABLE " \ -PRAGMA user_version = 50; \ -PRAGMA journal_mode = PERSIST; \ -PRAGMA foreign_keys = ON; \ -BEGIN EXCLUSIVE TRANSACTION; \ -CREATE TABLE IF NOT EXISTS complication_provider ( \ - pkgid TEXT NOT NULL, \ - appid TEXT NOT NULL, \ - provider_id TEXT NOT NULL, \ - period INTEGER DEFAULT -1, \ - support_type INTEGER DEFAULT 0, \ - default_data TEXT NOT NULL, \ - PRIMARY KEY (provider_id, support_type) \ -); \ -CREATE TABLE IF NOT EXISTS provider_localized_info ( \ - provider_id TEXT NOT NULL, \ - locale TEXT NOT NULL DEFAULT 'No Locale', \ - provider_label TEXT, \ - PRIMARY KEY (provider_id, locale) \ -); \ -CREATE TABLE IF NOT EXISTS provider_privilege ( \ - provider_id TEXT NOT NULL, \ - privilege TEXT NOT NULL, \ - PRIMARY KEY (provider_id, privilege) \ -); \ -CREATE TABLE IF NOT EXISTS provider_setup_appid ( \ - provider_id TEXT NOT NULL, \ - setup_appid TEXT, \ - PRIMARY KEY (provider_id) \ -); \ -COMMIT TRANSACTION; " - -#define COMPLICATION_TBL_COUNT 4 -static char *_complication_table_list[COMPLICATION_TBL_COUNT] = { - "complication_provider", - "provider_localized_info", - "provider_privilege", - "provider_setup_appid" -}; - -static int _is_global(uid_t uid) -{ - if (uid == ROOT_USER || uid == GLOBALAPP_USER) - return 1; - else - return 0; -} - -static const char *_get_db_path(uid_t uid) -{ - const char *path; - - if (!_is_global(uid)) - tzplatform_set_user(uid); - - path = tzplatform_mkpath(_is_global(uid) ? - TZ_SYS_DB : TZ_USER_DB, ".complication_provider.db"); - - tzplatform_reset_user(); - - return path; -} - -static int _db_busy_handler(void *data, int count) -{ - if (count < BUSY_WAITING_MAX) { - usleep(BUSY_WAITING_USEC); - return 1; - } - - /* sqlite3_prepare_v2 will return SQLITE_BUSY */ - return 0; -} - -static int _create_db(sqlite3 *db, const char *path) -{ - int ret; - - if (db) - sqlite3_close(db); - unlink(path); - - ret = sqlite3_open_v2(path, &db, - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - NULL); - if (ret != SQLITE_OK) { - unlink(path); - LOGE("create db fail"); - return -1; - } - - return ret; -} - -static int _check_table_exist(sqlite3 *db) -{ - int ret; - char *val; - int idx = 0; - sqlite3_stmt *stmt; - const char query[] = - "SELECT name FROM sqlite_master WHERE type='table'" - " ORDER BY name ASC"; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - LOGE("prepare error: %s", sqlite3_errmsg(db)); - return -1; - } - - while (sqlite3_step(stmt) == SQLITE_ROW - && idx < COMPLICATION_TBL_COUNT) { - val = (char *)sqlite3_column_text(stmt, 0); - - if (strcmp(_complication_table_list[idx], val) != 0) - continue; - - idx++; - } - - if (stmt) - sqlite3_finalize(stmt); - - if (idx != COMPLICATION_TBL_COUNT) { - LOGE("table count not matched"); - return -1; - } - - return 0; -} - -static int _create_table(sqlite3 *db) -{ - int ret; - char *errmsg = NULL; - - ret = sqlite3_exec(db, CREATE_COMPLICATION_TABLE, - NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - LOGE("create table fail : %s", errmsg); - sqlite3_free(errmsg); - return -1; - } - - return 0; -} - -int check_db(uid_t uid) -{ - int ret; - const char *path; - sqlite3 *db = NULL; - - path = _get_db_path(uid); - if (path == NULL) - return -1; - - ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { - ret = _create_db(db, path); - if (ret != SQLITE_OK) - return -1; - } - - if (_check_table_exist(db)) { - if (_create_table(db)) { - if (db) - sqlite3_close_v2(db); - - return -1; - } - } - - if (db) - sqlite3_close_v2(db); - - return 0; -} - -sqlite3 *open_db(uid_t uid) -{ - int ret; - sqlite3 *db; - const char *path; - - path = _get_db_path(uid); - if (access(path, F_OK) == -1) { - LOGE("db(%s) does not exist, create one", path); - return NULL; - } - - ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { - LOGE("open db(%s) error: %d", path, ret); - return NULL; - } - - ret = sqlite3_busy_handler(db, _db_busy_handler, NULL); - if (ret != SQLITE_OK) { - LOGE("Failed to register busy handler: %s", - sqlite3_errmsg(db)); - sqlite3_close_v2(db); - return NULL; - } - - /* turn on foreign keys */ - if (sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL)) { - sqlite3_close_v2(db); - return NULL; - } - - return db; -} diff --git a/parser/complication_parser_plugin_internal.cc b/parser/complication_parser_plugin_internal.cc new file mode 100644 index 0000000..3f3e178 --- /dev/null +++ b/parser/complication_parser_plugin_internal.cc @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include + +#include + +#include +#include + +#include "complication_parser_plugin_internal.h" + +#define BUSY_WAITING_USEC 50000 /* 0.05 sec */ +#define BUSY_WAITING_MAX 20 /* wait for max 1 sec */ +#define ROOT_USER 0 +#define GLOBALAPP_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) + +#define CREATE_COMPLICATION_TABLE " \ +PRAGMA user_version = 50; \ +PRAGMA journal_mode = PERSIST; \ +PRAGMA foreign_keys = ON; \ +BEGIN EXCLUSIVE TRANSACTION; \ +CREATE TABLE IF NOT EXISTS complication_provider ( \ + pkgid TEXT NOT NULL, \ + appid TEXT NOT NULL, \ + provider_id TEXT NOT NULL, \ + period INTEGER DEFAULT -1, \ + support_type INTEGER DEFAULT 0, \ + default_data TEXT NOT NULL, \ + PRIMARY KEY (provider_id, support_type) \ +); \ +CREATE TABLE IF NOT EXISTS provider_localized_info ( \ + provider_id TEXT NOT NULL, \ + locale TEXT NOT NULL DEFAULT 'No Locale', \ + provider_label TEXT, \ + PRIMARY KEY (provider_id, locale) \ +); \ +CREATE TABLE IF NOT EXISTS provider_privilege ( \ + provider_id TEXT NOT NULL, \ + privilege TEXT NOT NULL, \ + PRIMARY KEY (provider_id, privilege) \ +); \ +CREATE TABLE IF NOT EXISTS provider_setup_appid ( \ + provider_id TEXT NOT NULL, \ + setup_appid TEXT, \ + PRIMARY KEY (provider_id) \ +); \ +COMMIT TRANSACTION; " + +#define COMPLICATION_TBL_COUNT 4 +static const char* _complication_table_list[COMPLICATION_TBL_COUNT] = { + "complication_provider", + "provider_localized_info", + "provider_privilege", + "provider_setup_appid" +}; + +static int _is_global(uid_t uid) { + if (uid == ROOT_USER || uid == GLOBALAPP_USER) + return 1; + else + return 0; +} + +static const char* _get_db_path(uid_t uid) { + const char* path; + + if (!_is_global(uid)) + tzplatform_set_user(uid); + + path = tzplatform_mkpath(_is_global(uid) ? + TZ_SYS_DB : TZ_USER_DB, ".complication_provider.db"); + + tzplatform_reset_user(); + + return path; +} + +static int _db_busy_handler(void* data, int count) { + if (count < BUSY_WAITING_MAX) { + usleep(BUSY_WAITING_USEC); + return 1; + } + + /* sqlite3_prepare_v2 will return SQLITE_BUSY */ + return 0; +} + +static int _create_db(sqlite3* db, const char* path) { + int ret; + + if (db) + sqlite3_close(db); + unlink(path); + + ret = sqlite3_open_v2(path, &db, + SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, + NULL); + if (ret != SQLITE_OK) { + unlink(path); + LOGE("create db fail"); + return -1; + } + + return ret; +} + +static int _check_table_exist(sqlite3* db) { + int ret; + char* val; + int idx = 0; + sqlite3_stmt* stmt; + const char query[] = + "SELECT name FROM sqlite_master WHERE type='table'" + " ORDER BY name ASC"; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + while (sqlite3_step(stmt) == SQLITE_ROW + && idx < COMPLICATION_TBL_COUNT) { + val = (char*)sqlite3_column_text(stmt, 0); + + if (strcmp(_complication_table_list[idx], val) != 0) + continue; + + idx++; + } + + if (stmt) + sqlite3_finalize(stmt); + + if (idx != COMPLICATION_TBL_COUNT) { + LOGE("table count not matched"); + return -1; + } + + return 0; +} + +static int _create_table(sqlite3* db) { + int ret; + char* errmsg = NULL; + + ret = sqlite3_exec(db, CREATE_COMPLICATION_TABLE, + NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + LOGE("create table fail : %s", errmsg); + sqlite3_free(errmsg); + return -1; + } + + return 0; +} + +int check_db(uid_t uid) { + int ret; + const char* path; + sqlite3* db = NULL; + + path = _get_db_path(uid); + if (path == NULL) + return -1; + + ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); + if (ret != SQLITE_OK) { + ret = _create_db(db, path); + if (ret != SQLITE_OK) + return -1; + } + + if (_check_table_exist(db)) { + if (_create_table(db)) { + if (db) + sqlite3_close_v2(db); + + return -1; + } + } + + if (db) + sqlite3_close_v2(db); + + return 0; +} + +sqlite3* open_db(uid_t uid) { + int ret; + sqlite3* db; + const char* path; + + path = _get_db_path(uid); + if (access(path, F_OK) == -1) { + LOGE("db(%s) does not exist, create one", path); + return NULL; + } + + ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); + if (ret != SQLITE_OK) { + LOGE("open db(%s) error: %d", path, ret); + return NULL; + } + + ret = sqlite3_busy_handler(db, _db_busy_handler, NULL); + if (ret != SQLITE_OK) { + LOGE("Failed to register busy handler: %s", + sqlite3_errmsg(db)); + sqlite3_close_v2(db); + return NULL; + } + + /* turn on foreign keys */ + if (sqlite3_exec(db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL)) { + sqlite3_close_v2(db); + return NULL; + } + + return db; +} diff --git a/parser/complication_parser_plugin_internal.h b/parser/complication_parser_plugin_internal.h index 9007b1c..cce00f9 100644 --- a/parser/complication_parser_plugin_internal.h +++ b/parser/complication_parser_plugin_internal.h @@ -23,8 +23,8 @@ #include #include -#ifndef API -#define API __attribute__ ((visibility("default"))) +#ifndef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) #endif #ifdef LOG_TAG diff --git a/parser/complication_parser_plugin_pkgmgr_interface.c b/parser/complication_parser_plugin_pkgmgr_interface.c deleted file mode 100644 index 0271fce..0000000 --- a/parser/complication_parser_plugin_pkgmgr_interface.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. - * - * 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 - -#include - -#include "complication_parser_plugin_internal.h" - -API int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char *pkgid) -{ - return complication_parser_plugin_init(); -} - -API int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char *pkgid) -{ - if (complication_parser_plugin_parse_manifest(doc, pkgid)) { - LOGE("parse failed"); - return -1; - } - - return 0; -} - -API int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *pkgid) -{ - return complication_parser_plugin_fini(); -} - -API int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char *pkgid) -{ - return complication_parser_plugin_init(); -} - -API int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc, const char *pkgid) -{ - if (complication_parser_db_remove_complication(pkgid)) { - LOGE("remove db fail"); - return -1; - } - - if (complication_parser_plugin_parse_manifest(doc, pkgid)) { - LOGE("parse failed"); - return -1; - } - - return 0; -} - -API int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *pkgid) -{ - return complication_parser_plugin_fini(); -} - -API int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char *pkgid) -{ - return complication_parser_plugin_init(); -} - -API int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc, const char *pkgid) -{ - return complication_parser_db_remove_complication(pkgid); -} - -API int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char *pkgid) -{ - return complication_parser_plugin_fini(); -} diff --git a/parser/complication_parser_plugin_pkgmgr_interface.cc b/parser/complication_parser_plugin_pkgmgr_interface.cc new file mode 100644 index 0000000..b4af9bc --- /dev/null +++ b/parser/complication_parser_plugin_pkgmgr_interface.cc @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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 + +#include + +#include "complication_parser_plugin_internal.h" + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char* pkgid) { + return complication_parser_plugin_init(); +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgid) { + if (complication_parser_plugin_parse_manifest(doc, pkgid)) { + LOGE("parse failed"); + return -1; + } + + return 0; +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char* pkgid) { + return complication_parser_plugin_fini(); +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char* pkgid) { + return complication_parser_plugin_init(); +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc, const char* pkgid) { + if (complication_parser_db_remove_complication(pkgid)) { + LOGE("remove db fail"); + return -1; + } + + if (complication_parser_plugin_parse_manifest(doc, pkgid)) { + LOGE("parse failed"); + return -1; + } + + return 0; +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char* pkgid) { + return complication_parser_plugin_fini(); +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char* pkgid) { + return complication_parser_plugin_init(); +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc, const char* pkgid) { + return complication_parser_db_remove_complication(pkgid); +} + +extern "C" EXPORT_API int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char* pkgid) { + return complication_parser_plugin_fini(); +} -- 2.7.4