Fix get default value bug 04/180304/6
authorhyunho <hhstark.kang@samsung.com>
Mon, 28 May 2018 06:37:45 +0000 (15:37 +0900)
committerhyunho <hhstark.kang@samsung.com>
Tue, 29 May 2018 01:06:25 +0000 (10:06 +0900)
Change-Id: I239b7c9e0ecf1b8a726d84eae98308964cd1bfec
Signed-off-by: hyunho <hhstark.kang@samsung.com>
parser/CMakeLists.txt
parser/complication_parser_plugin.c [deleted file]
parser/complication_parser_plugin.cc [new file with mode: 0644]
parser/complication_parser_plugin_internal.c [deleted file]
parser/complication_parser_plugin_internal.cc [new file with mode: 0644]
parser/complication_parser_plugin_internal.h
parser/complication_parser_plugin_pkgmgr_interface.c [deleted file]
parser/complication_parser_plugin_pkgmgr_interface.cc [new file with mode: 0644]

index c6889a6..249cdd5 100644 (file)
@@ -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 (file)
index 1b5c00e..0000000
+++ /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 <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <libxml/tree.h>
-
-#include <dlog.h>
-
-#include <pkgmgr-info.h>
-#include <pkgmgr_installer_info.h>
-#include <bundle.h>
-
-#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 (file)
index 0000000..8582858
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <libxml/tree.h>
+
+#include <dlog.h>
+
+#include <pkgmgr-info.h>
+#include <pkgmgr_installer_info.h>
+#include <bundle.h>
+
+#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 (file)
index 70ee9cf..0000000
+++ /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 <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sqlite3.h>
-
-#include <dlog.h>
-#include <tzplatform_config.h>
-
-#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 (file)
index 0000000..3f3e178
--- /dev/null
@@ -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 <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <sqlite3.h>
+
+#include <dlog.h>
+#include <tzplatform_config.h>
+
+#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;
+}
index 9007b1c..cce00f9 100644 (file)
@@ -23,8 +23,8 @@
 #include <libxml/tree.h>
 #include <sqlite3.h>
 
-#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 (file)
index 0271fce..0000000
+++ /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 <libxml/tree.h>
-
-#include <dlog.h>
-
-#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 (file)
index 0000000..b4af9bc
--- /dev/null
@@ -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 <libxml/tree.h>
+
+#include <dlog.h>
+
+#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();
+}