From 9a237e4ff2720421114fad06f9163ac0341c620d Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 18 Nov 2015 13:28:10 +0900 Subject: Add widget-plugin-parser source codes note that data structures and related functions at 'widget_plugin_parser_internal.h' could be separated Change-Id: I0b236b9701572a43818b3b804b7057b3c22b7d85 Signed-off-by: Sangyoon Jang --- CMakeLists.txt | 2 + packaging/libwidget_service.spec | 17 +- parser/CMakeLists.txt | 26 ++ parser/widget.sql | 40 +++ parser/widget_plugin_parser.c | 330 +++++++++++++++++++++++++ parser/widget_plugin_parser_db.c | 303 +++++++++++++++++++++++ parser/widget_plugin_parser_internal.c | 137 ++++++++++ parser/widget_plugin_parser_internal.h | 62 +++++ parser/widget_plugin_parser_pkgmgr_interface.c | 96 +++++++ 9 files changed, 1012 insertions(+), 1 deletion(-) create mode 100644 parser/CMakeLists.txt create mode 100644 parser/widget.sql create mode 100644 parser/widget_plugin_parser.c create mode 100644 parser/widget_plugin_parser_db.c create mode 100644 parser/widget_plugin_parser_internal.c create mode 100644 parser/widget_plugin_parser_internal.h create mode 100644 parser/widget_plugin_parser_pkgmgr_interface.c diff --git a/CMakeLists.txt b/CMakeLists.txt index af447ea..04d74d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,4 +122,6 @@ ENDIF (WAYLAND_SUPPORT) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}") +ADD_SUBDIRECTORY(parser) + # End of a file diff --git a/packaging/libwidget_service.spec b/packaging/libwidget_service.spec index 490947a..3088406 100644 --- a/packaging/libwidget_service.spec +++ b/packaging/libwidget_service.spec @@ -24,6 +24,8 @@ BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(libxml-2.0) %if %{with wayland} BuildRequires: pkgconfig(wayland-client) @@ -80,15 +82,25 @@ export WAYLAND_SUPPORT=Off export X11_SUPPORT=On %endif +sqlite3 .widget.db < ./parser/widget.sql + %cmake . -DWAYLAND_SUPPORT=${WAYLAND_SUPPORT} -DX11_SUPPORT=${X11_SUPPORT} make %{?jobs:-j%jobs} %install rm -rf %{buildroot} %make_install -mkdir -p %{buildroot}/%{_datarootdir}/license +mkdir -p %{buildroot}%{_datarootdir}/license +mkdir -p %{buildroot}%{TZ_SYS_DB} +mkdir -p %{buildroot}%{_sysconfdir}/skel/.applications/dbspace + +install -m 0644 .widget.db %{buildroot}%{TZ_SYS_DB} +install -m 0644 .widget.db %{buildroot}%{_sysconfdir}/skel/.applications/dbspace %post -n %{name} -p /sbin/ldconfig +chsmack -a "User::Home" %{TZ_SYS_DB}/.widget.db +chsmack -a "User::Home" %{_sysconfdir}/skel/.applications/dbspace/.widget.db + %postun -n %{name} -p /sbin/ldconfig %files -n %{name} @@ -96,6 +108,9 @@ mkdir -p %{buildroot}/%{_datarootdir}/license %defattr(-,root,root,-) %{_libdir}/libwidget_service.so* %{_datarootdir}/license/libwidget_service +%{_sysconfdir}/package-manager/parserlib/libwidget-application.so +%{_sysconfdir}/skel/.applications/dbspace/.widget.db +%{TZ_SYS_DB}/.widget.db %files devel %manifest %{name}.manifest diff --git a/parser/CMakeLists.txt b/parser/CMakeLists.txt new file mode 100644 index 0000000..95c5697 --- /dev/null +++ b/parser/CMakeLists.txt @@ -0,0 +1,26 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(widget-plugin-parser C) + +SET(SRCS + widget_plugin_parser.c + widget_plugin_parser_db.c + widget_plugin_parser_internal.c + widget_plugin_parser_pkgmgr_interface.c + ) + +pkg_check_modules(PKGS REQUIRED + glib-2.0 + sqlite3 + libxml-2.0 + dlog + libtzplatform-config + ) +FOREACH(FLAGS ${PKGS_CFLAGS}) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}") +ENDFOREACH(FLAGS) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fPIC") + +ADD_LIBRARY(widget-application MODULE ${SRCS}) + +INSTALL(TARGETS widget-application DESTINATION ${SYSCONF_INSTALL_DIR}/package-manager/parserlib/) diff --git a/parser/widget.sql b/parser/widget.sql new file mode 100644 index 0000000..6984494 --- /dev/null +++ b/parser/widget.sql @@ -0,0 +1,40 @@ +PRAGMA tizen_version = 30; /* Tizen 3.0 */ +PRAGMA db_version = 1; +PRAGMA journal_mode = PERSIST; +PRAGMA foreign_keys = ON; + +BEGIN EXCLUSIVE TRANSACTION; + +CREATE TABLE widget_class ( + classid TEXT NOT NULL, + update_period INTEGER DEFAULT 0, + setup_appid TEXT, + appid TEXT NOT NULL, + pkgid TEXT NOT NULL, + PRIMARY KEY(classid) +); + +CREATE TABLE support_size ( + classid TEXT NOT NULL, + preview TEXT NOT NULL, + frame INTEGER DEFAULT 0, + width INTEGER NOT NULL, + height INTEGER NOT NULL, + FOREIGN KEY(classid) REFERENCES widget_class (classid) ON DELETE CASCADE +); + +CREATE TABLE label ( + classid TEXT NOT NULL, + locale TEXT DEFAULT 'No Locale', + label TEXT NOT NULL, + FOREIGN KEY(classid) REFERENCES widget_class (classid) ON DELETE CASCADE +); + +CREATE TABLE icon ( + classid TEXT NOT NULL, + locale TEXT DEFAULT 'No Locale', + icon TEXT NOT NULL, + FOREIGN KEY(classid) REFERENCES widget_class (classid) ON DELETE CASCADE +); + +COMMIT TRANSACTION; diff --git a/parser/widget_plugin_parser.c b/parser/widget_plugin_parser.c new file mode 100644 index 0000000..e68c0e4 --- /dev/null +++ b/parser/widget_plugin_parser.c @@ -0,0 +1,330 @@ +/* + * Copyright 2015 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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 "widget_plugin_parser_internal.h" + +enum widget_tag { + TAG_WIDGET_APPLICATION = 1, + TAG_WIDGET_CLASS, + TAG_LABEL, + TAG_ICON, + TAG_SUPPORT_SIZE, +}; + +struct tag_map { + char *name; + enum widget_tag tag; +}; + +struct tag_map map[] = { + { "widget-application", TAG_WIDGET_APPLICATION }, + { "widget-class", TAG_WIDGET_CLASS }, + { "label", TAG_LABEL }, + { "icon", TAG_ICON }, + { "support-size", TAG_SUPPORT_SIZE } +}; +static GHashTable *tag_table; + +int widget_plugin_parser_init(void) +{ + int i; + + if (tag_table) + return 0; + + tag_table = g_hash_table_new(g_int_hash, g_str_equal); + if (tag_table == NULL) + return -1; + + for (i = 0; i < (sizeof(map) / sizeof(struct tag_map)); i++) + g_hash_table_insert(tag_table, map[i].name, + (gpointer)map[i].tag); + + return 0; +} + +int widget_plugin_parser_fini(void) +{ + if (!tag_table) + return 0; + + g_hash_table_destroy(tag_table); + tag_table = NULL; + + 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 enum widget_tag _get_tag(xmlNode *node) +{ + return (enum widget_tag)g_hash_table_lookup(tag_table, node->name); +} + +static int _parse_support_size(xmlNode *node, GList **sizes) +{ + char *val; + struct support_size *size; + char *tok; + char *ptr; + + if (node->children == NULL || node->children->content == NULL) + return -1; + + size = calloc(1, sizeof(struct support_size)); + if (size == NULL) + return -1; + + val = strdup((char *)node->children->content); + tok = strtok_r(val, "xX", &ptr); + if (tok == NULL) { + free(size); + return -1; + } + size->width = atoi(tok); + tok = strtok_r(NULL, "xX", &ptr); + if (tok == NULL) { + free(size); + return -1; + } + size->height = atoi(tok); + free(val); + + size->preview = _get_attribute(node, "preview"); + val = _get_attribute(node, "frame"); + if (val && !strcasecmp(val, "true")) { + size->frame = true; + free(val); + } + + *sizes = g_list_append(*sizes, size); + + return 0; +} + +static int _parse_icon(xmlNode *node, GList **icons) +{ + struct icon *icon; + + if (node->children == NULL || node->children->content == NULL) + return -1; + + icon = calloc(1, sizeof(struct icon)); + if (icon == NULL) + return -1; + + icon->icon = strdup((char *)node->children->content); + icon->lang = _get_attribute(node, "lang"); + + *icons = g_list_append(*icons, icon); + + return 0; +} + +static int _parse_label(xmlNode *node, GList **labels) +{ + struct label *label; + + if (node->children == NULL || node->children->content == NULL) + return -1; + + label = calloc(1, sizeof(struct label)); + if (label == NULL) + return -1; + + label->label = strdup((char *)node->children->content); + label->lang = _get_attribute(node, "lang"); + + *labels = g_list_append(*labels, label); + + return 0; +} + +static int _parse_widget_class(xmlNode *node, const char *appid, GList **apps) +{ + char *val; + xmlNode *tmp; + struct widget_class *wc; + char buf[128]; + + wc = calloc(1, sizeof(struct widget_class)); + if (wc == NULL) + return -1; + wc->appid = strdup(appid); + + val = _get_attribute(node, "classid"); + if (val == NULL) { + free(wc); + return -1; + } + snprintf(buf, sizeof(buf), "%s@%s", val, appid); + free(val); + wc->classid = strdup(buf); + + val = _get_attribute(node, "update-period"); + if (val) + wc->update_period = atoi(val); + free(val); + + wc->setup_appid = _get_attribute(node, "setup-appid"); + + for (tmp = node->children; tmp; tmp = tmp->next) { + switch (_get_tag(tmp)) { + case TAG_SUPPORT_SIZE: + if (_parse_support_size(tmp, &wc->support_size)) { + _free_widget_class((gpointer)wc); + return -1; + } + break; + case TAG_ICON: + if (_parse_icon(tmp, &wc->icon)) { + _free_widget_class((gpointer)wc); + return -1; + } + break; + case TAG_LABEL: + if (_parse_label(tmp, &wc->label)) { + _free_widget_class((gpointer)wc); + return -1; + } + break; + default: + /* unexpected tag */ + continue; + } + } + + *apps = g_list_append(*apps, wc); + + return 0; +} + +static int _parse_widget_application(xmlNode *node, GList **list) +{ + char *val; + xmlNode *tmp; + struct widget_class *wc; + + wc = calloc(1, sizeof(struct widget_class)); + if (wc == NULL) + return -1; + + val = _get_attribute(node, "appid"); + if (val == NULL) { + free(wc); + return -1; + } + wc->appid = val; + wc->classid = strdup(wc->appid); + + val = _get_attribute(node, "update-period"); + if (val) + wc->update_period = atoi(val); + + wc->setup_appid = _get_attribute(node, "setup-appid"); + + for (tmp = node->children; tmp; tmp = tmp->next) { + switch (_get_tag(tmp)) { + case TAG_SUPPORT_SIZE: + if (_parse_support_size(tmp, &wc->support_size)) { + _free_widget_class((gpointer)wc); + return -1; + } + break; + case TAG_ICON: + if (_parse_icon(tmp, &wc->icon)) { + _free_widget_class((gpointer)wc); + return -1; + } + break; + case TAG_LABEL: + if (_parse_label(tmp, &wc->label)) { + _free_widget_class((gpointer)wc); + return -1; + } + break; + case TAG_WIDGET_CLASS: + if (_parse_widget_class(tmp, wc->appid, list)) { + _free_widget_class((gpointer)wc); + return -1; + } + default: + continue; + } + } + + *list = g_list_append(*list, wc); + + return 0; +} + +GList *widget_plugin_parser_parse_manifest(xmlDocPtr doc) +{ + xmlNode *root; + xmlNode *tmp; + GList *list = NULL; + + if (!tag_table) { + LOGE("parser is not initialized"); + return NULL; + } + + if (doc == NULL) { + LOGE("invalid parameter"); + return NULL; + } + + root = xmlDocGetRootElement(doc); + if (root == NULL) { + LOGE("failed to get root element"); + return NULL; + } + + for (tmp = root->children; tmp; tmp = tmp->next) { + if (_get_tag(tmp) != TAG_WIDGET_APPLICATION) + continue; + + if (_parse_widget_application(tmp, &list)) { + LOGE("parse failed"); + return NULL; + } + } + + return list; +} diff --git a/parser/widget_plugin_parser_db.c b/parser/widget_plugin_parser_db.c new file mode 100644 index 0000000..4d2c5c0 --- /dev/null +++ b/parser/widget_plugin_parser_db.c @@ -0,0 +1,303 @@ +/* + * Copyright 2015 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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 "widget_plugin_parser_internal.h" + +static int _bind_text(sqlite3_stmt *stmt, int idx, const char *text) +{ + if (text) + return sqlite3_bind_text(stmt, idx, text, -1, SQLITE_STATIC); + else + return sqlite3_bind_null(stmt, idx); +} + +static int _insert_support_size(sqlite3 *db, const char *classid, GList *sizes) +{ + int ret; + static const char query[] = + "INSERT INTO support_size " + "(classid, preview, frame, width, height) " + "VALUES (?, ?, ?, ?, ?)"; + GList *tmp; + struct support_size *size; + sqlite3_stmt *stmt = NULL; + int idx; + + for (tmp = sizes; tmp; tmp = tmp->next) { + size = (struct support_size *)tmp->data; + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + idx = 1; + _bind_text(stmt, idx++, classid); + _bind_text(stmt, idx++, size->preview); + sqlite3_bind_int(stmt, idx++, size->frame); + sqlite3_bind_int(stmt, idx++, size->width); + sqlite3_bind_int(stmt, idx++, size->height); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + return -1; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + } + + if (stmt) + sqlite3_finalize(stmt); + + return 0; +} + +static int _insert_label(sqlite3 *db, const char *classid, GList *labels) +{ + int ret; + static const char query[] = + "INSERT INTO label (classid, locale, label) " + "VALUES (?, ?, ?)"; + GList *tmp; + struct label *label; + sqlite3_stmt *stmt = NULL; + int idx; + + for (tmp = labels; tmp; tmp = tmp->next) { + label = (struct label *)tmp->data; + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + idx = 1; + _bind_text(stmt, idx++, classid); + _bind_text(stmt, idx++, label->lang); + _bind_text(stmt, idx++, label->label); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + return -1; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + } + + if (stmt) + sqlite3_finalize(stmt); + + return 0; +} + +static int _insert_icon(sqlite3 *db, const char *classid, GList *icons) +{ + int ret; + static const char query[] = + "INSERT INTO icon (classid, locale, icon) " + "VALUES (?, ?, ?)"; + GList *tmp; + struct icon *icon; + sqlite3_stmt *stmt = NULL; + int idx; + + for (tmp = icons; tmp; tmp = tmp->next) { + icon = (struct icon *)tmp->data; + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + idx = 1; + _bind_text(stmt, idx++, classid); + _bind_text(stmt, idx++, icon->lang); + _bind_text(stmt, idx++, icon->icon); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + return -1; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + } + + if (stmt) + sqlite3_finalize(stmt); + + return 0; +} + +static int _insert_widget_class(sqlite3 *db, const char *pkgid, GList *wcs) +{ + int ret; + static const char query[] = + "INSERT INTO widget_class (classid, update_period, " + "setup_appid, appid, pkgid) " + "VALUES (?, ?, ?, ?, ?)"; + GList *tmp; + struct widget_class *wc; + sqlite3_stmt *stmt = NULL; + int idx; + + for (tmp = wcs; tmp; tmp = tmp->next) { + wc = (struct widget_class *)tmp->data; + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + idx = 1; + _bind_text(stmt, idx++, wc->classid); + sqlite3_bind_int(stmt, idx++, wc->update_period); + _bind_text(stmt, idx++, wc->setup_appid); + _bind_text(stmt, idx++, wc->appid); + _bind_text(stmt, idx++, pkgid); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_DONE) { + LOGE("step error: %s", sqlite3_errmsg(db)); + break; + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + + if (_insert_support_size(db, wc->classid, wc->support_size)) + return -1; + if (_insert_label(db, wc->classid, wc->label)) + return -1; + if (_insert_icon(db, wc->classid, wc->icon)) + return -1; + } + + if (stmt) + sqlite3_finalize(stmt); + + return 0; +} + +int widget_parser_db_insert_widget_class(const char *pkgid, GList *widget_list) +{ + int ret; + sqlite3 *db; + + db = _open_db(getuid(), false); + if (db == NULL) + return -1; + + if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + sqlite3_close_v2(db); + return -1; + } + + ret = _insert_widget_class(db, pkgid, widget_list); + if (ret) { + LOGE("failed to insert widget class data"); + sqlite3_close_v2(db); + return -1; + } + + if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + sqlite3_close_v2(db); + return -1; + } + + _close_db(db); + + return 0; +} + +static int _remove_widget_class(sqlite3 *db, const char *pkgid) +{ + int ret; + static const char query[] = + "DELETE FROM widget_class WHERE pkgid=?"; + sqlite3_stmt *stmt = NULL; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + LOGE("prepare error: %s", sqlite3_errmsg(db)); + return -1; + } + + _bind_text(stmt, 1, pkgid); + + 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 widget_parser_db_remove_widget_class(const char *pkgid) +{ + int ret; + sqlite3 *db; + + db = _open_db(getuid(), false); + if (db == NULL) + return -1; + + if (sqlite3_exec(db, "BEGIN TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + sqlite3_close_v2(db); + return -1; + } + + ret = _remove_widget_class(db, pkgid); + if (ret) { + LOGE("failed to remove widget class data"); + sqlite3_close_v2(db); + return -1; + } + + if (sqlite3_exec(db, "END TRANSACTION", NULL, NULL, NULL)) { + LOGE("begin transaction error"); + sqlite3_close_v2(db); + return -1; + } + + _close_db(db); + + return 0; +} diff --git a/parser/widget_plugin_parser_internal.c b/parser/widget_plugin_parser_internal.c new file mode 100644 index 0000000..ddc5239 --- /dev/null +++ b/parser/widget_plugin_parser_internal.c @@ -0,0 +1,137 @@ +/* + * Copyright 2015 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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 "widget_plugin_parser_internal.h" + +void _free_support_size(gpointer data) +{ + struct support_size *size = (struct support_size *)data; + + if (size == NULL) + return; + + free(size->preview); + free(size); +} + +void _free_label(gpointer data) +{ + struct label *label = (struct label *)data; + + if (label == NULL) + return; + + free(label->label); + free(label->lang); + free(label); +} + +void _free_icon(gpointer data) +{ + struct icon *icon = (struct icon *)data; + + if (icon == NULL) + return; + + free(icon->icon); + free(icon->lang); + free(icon); +} + +void _free_widget_class(gpointer data) +{ + struct widget_class *wc = (struct widget_class *)data; + + if (wc == NULL) + return; + + free(wc->classid); + free(wc->setup_appid); + free(wc->appid); + + g_list_free_full(wc->support_size, _free_support_size); + g_list_free_full(wc->label, _free_label); + g_list_free_full(wc->icon, _free_icon); + + free(wc); +} + +#define ROOT_USER 0 +#define GLOBALAPP_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) +static int _is_global(uid_t uid) +{ + if (uid == ROOT_USER || uid == GLOBALAPP_USER) + return 1; + else + return 0; +} + +static 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, ".widget.db"); + + tzplatform_reset_user(); + + return strdup(path); +} + +sqlite3 *_open_db(uid_t uid, bool readonly) +{ + int ret; + sqlite3 *db; + char *path; + + path = _get_db_path(uid); + + if (access(path, F_OK) == -1) { + LOGD("db(%s) does not exist, create one", path); + return NULL; + } + + ret = sqlite3_open_v2(path, &db, + readonly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE, + NULL); + if (ret != SQLITE_OK) { + LOGE("open db(%s) error: %d", path, ret); + free(path); + return NULL; + } + + free(path); + + return db; +} + +void _close_db(sqlite3 *db) +{ + sqlite3_close_v2(db); +} diff --git a/parser/widget_plugin_parser_internal.h b/parser/widget_plugin_parser_internal.h new file mode 100644 index 0000000..8f274de --- /dev/null +++ b/parser/widget_plugin_parser_internal.h @@ -0,0 +1,62 @@ +#ifndef __WIDGET_PLUGIN_PARSER_INTERNAL_H__ +#define __WIDGET_PLUGIN_PARSER_INTERNAL_H__ + +#include +#include + +#include +#include +#include + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "WIDGET_PLUGIN_PARSER" +#endif + +struct support_size { + char *preview; + bool frame; + int width; + int height; +}; + +struct label { + char *label; + char *lang; +}; + +struct icon { + char *icon; + char *lang; +}; + +struct widget_class { + char *classid; + int update_period; + char *setup_appid; + char *appid; + GList *support_size; + GList *label; + GList *icon; +}; + +int widget_plugin_parser_init(void); +int widget_plugin_parser_fini(void); +GList *widget_plugin_parser_parse_manifest(xmlDocPtr doc); + + +int widget_parser_db_insert_widget_class(const char *pkgid, GList *widget_list); +int widget_parser_db_remove_widget_class(const char *pkgid); + +void _free_widget_class(gpointer data); + +sqlite3 *_open_db(uid_t uid, bool readonly); +void _close_db(sqlite3 *db); + +int widget_info_get_widget_class(const char *classid, struct widget_class **wc); + +#endif diff --git a/parser/widget_plugin_parser_pkgmgr_interface.c b/parser/widget_plugin_parser_pkgmgr_interface.c new file mode 100644 index 0000000..19ca969 --- /dev/null +++ b/parser/widget_plugin_parser_pkgmgr_interface.c @@ -0,0 +1,96 @@ +/* + * Copyright 2015 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * 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 "widget_plugin_parser_internal.h" + +API int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char *pkgid) +{ + return widget_plugin_parser_init(); +} + +API int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char *pkgid) +{ + GList *result; + + result = widget_plugin_parser_parse_manifest(doc); + if (result == NULL) { + LOGE("parse failed"); + return -1; + } + + if (widget_parser_db_insert_widget_class(pkgid, result)) + return -1; + + g_list_free_full(result, _free_widget_class); + + return 0; +} + +API int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *pkgid) +{ + return widget_plugin_parser_fini(); +} + +API int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char *pkgid) +{ + return widget_plugin_parser_init(); +} + +API int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc, const char *pkgid) +{ + GList *result; + + result = widget_plugin_parser_parse_manifest(doc); + if (result == NULL) { + LOGE("parse failed"); + return -1; + } + + if (widget_parser_db_remove_widget_class(pkgid)) + return -1; + + if (widget_parser_db_insert_widget_class(pkgid, result)) + return -1; + + g_list_free_full(result, _free_widget_class); + + return 0; +} + +API int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *pkgid) +{ + return widget_plugin_parser_fini(); +} + +API int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char *pkgid) +{ + return widget_plugin_parser_init(); +} + +API int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc, const char *pkgid) +{ + return widget_parser_db_remove_widget_class(pkgid); +} + +API int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char *pkgid) +{ + return widget_plugin_parser_fini(); +} -- cgit v1.2.3