From 69cf076913e05a880ef63d626d574448f9f6e994 Mon Sep 17 00:00:00 2001 From: Kwangyoun Kim Date: Thu, 8 Sep 2016 19:00:18 +0900 Subject: [PATCH] Add engine app info parser Change-Id: Iab0841cf7ebb90c22323f7c77251fe64049f927b --- 500.stt_upgrade_24to30.sh | 32 ++++ CMakeLists.txt | 5 + engine-parser/CMakeLists.txt | 37 +++++ engine-parser/src/stt-engine-parser.c | 284 ++++++++++++++++++++++++++++++++++ packaging/stt.spec | 6 + 5 files changed, 364 insertions(+) create mode 100755 500.stt_upgrade_24to30.sh create mode 100644 engine-parser/CMakeLists.txt create mode 100644 engine-parser/src/stt-engine-parser.c diff --git a/500.stt_upgrade_24to30.sh b/500.stt_upgrade_24to30.sh new file mode 100755 index 0000000..27cd36d --- /dev/null +++ b/500.stt_upgrade_24to30.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +#------------------------------------------# +# Resourced patch for upgrade (2.4 -> 3.0) # +#------------------------------------------# + +# Macro +VOICE_DIR_24=/opt/usr/data/voice +STT_CONF_DIR_24=/opt/home/app/.voice +STT_CONF_FILE_24=$STT_CONF_DIR_24/stt-config.xml + +VOICE_DIR_30=/opt/usr/home/owner/share/.voice +STT_CONF_FILE_30=$VOICE_DIR_30/stt-config.xml + +# Make new directories +mkdir -p $VOICE_DIR_30 +chown owner:users $VOICE_DIR_30 +chsmack -a User::App::Shared $VOICE_DIR_30 + + +# Move +mv $VOICE_DIR_24/stt/ $VOICE_DIR_30/ +chown -R owner:users $VOICE_DIR_30/ +chsmack -ra User::App::Shared $VOICE_DIR_30/ + +mv $STT_CONF_FILE_24 $STT_CONF_FILE_30 +chown owner:users $STT_CONF_FILE_30 +chsmack -a User::App::Shared $STT_CONF_FILE_30 + +# Remove directories +rm -r /opt/usr/devel/bin/stt-test +rm -rf $VOICE_DIR_24/stt diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e4d43c..6ef8f9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,9 @@ ADD_SUBDIRECTORY(server) ## Test ## ADD_SUBDIRECTORY(test) +## Engine Parser ## +ADD_SUBDIRECTORY(engine-parser) + ## config ## INSTALL(FILES ${CMAKE_SOURCE_DIR}/stt-config.xml DESTINATION ${TZ_SYS_RO_SHARE}/voice/stt/1.0) @@ -69,3 +72,5 @@ INSTALL(FILES ${CMAKE_SOURCE_DIR}/stt-config.xml DESTINATION ${TZ_SYS_RO_SHARE}/ INSTALL(FILES ${CMAKE_SOURCE_DIR}/org.tizen.voice.sttserver.service DESTINATION ${TZ_SYS_RO_SHARE}/dbus-1/services) INSTALL(FILES ${CMAKE_SOURCE_DIR}/stt-server.conf DESTINATION /etc/dbus-1/session.d) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/500.stt_upgrade_24to30.sh DESTINATION ${TZ_SYS_RO_SHARE}/upgrade/scripts) + diff --git a/engine-parser/CMakeLists.txt b/engine-parser/CMakeLists.txt new file mode 100644 index 0000000..c4ce6eb --- /dev/null +++ b/engine-parser/CMakeLists.txt @@ -0,0 +1,37 @@ +pkg_check_modules(parser-pkgs REQUIRED + capi-base-common + dlog + glib-2.0 + libxml-2.0 + pkgmgr-info + pkgmgr-installer + capi-appfw-app-manager + libtzplatform-config +) + +FOREACH(flag ${parser-pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET (SRCS + src/stt-engine-parser.c +) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall" ) +SET(extapi "-fvisibility=hidden") + +## SET C COMPILER FLAGS +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${extapi}") + +## SET CPP COMPILER FLAGS +#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +#SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") + +## SET LINKER FLAGS +SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed") + +## Create Library +ADD_LIBRARY ("${PROJECT_NAME}-engine-parser" SHARED ${SRCS}) +TARGET_LINK_LIBRARIES("${PROJECT_NAME}-engine-parser" ${parser-pkgs_LDFLAGS} ) + +INSTALL(TARGETS "${PROJECT_NAME}-engine-parser" DESTINATION "/etc/package-manager/parserlib/metadata") diff --git a/engine-parser/src/stt-engine-parser.c b/engine-parser/src/stt-engine-parser.c new file mode 100644 index 0000000..c1de50a --- /dev/null +++ b/engine-parser/src/stt-engine-parser.c @@ -0,0 +1,284 @@ +// +// Copyright (c) 2016 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 +#include + +/* Define EXPORT_API */ +#ifndef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "stt-engine-parser" + +#define STT_TAG_ENGINE_BASE "stt-engine" +#define STT_TAG_ENGINE_NAME "name" +#define STT_TAG_ENGINE_ID "id" +#define STT_TAG_ENGINE_SETTING "setting" +#define STT_TAG_ENGINE_LANGUAGE_SET "languages" +#define STT_TAG_ENGINE_LANGUAGE "lang" +#define STT_TAG_ENGINE_SILENCE_DETECTION_SUPPORT "silence-detection-support" +#define STT_TAG_ENGINE_CREDENTIAL "credential" + +#define STT_CONFIG_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice") +#define STT_HOME tzplatform_mkpath(TZ_USER_HOME, "share/.voice/stt") +#define STT_ENGINE_BASE tzplatform_mkpath(TZ_USER_HOME, "share/.voice/stt/1.0") +#define STT_ENGINE_INFO tzplatform_mkpath(TZ_USER_HOME, "/share/.voice/stt/1.0/engine-info") + +#define STT_METADATA_LANGUAGE "http://tizen.org/metadata/stt-engine/language" +#define STT_METADATA_SILENCE_DETECTION "http://tizen.org/metadata/stt-engine/silence-detection" +#define STT_METADATA_CREDENTIAL_REQUIRED "http://tizen.org/metadata/stt-engine/credential-required" + +typedef struct metadata { + const char *key; + const char *value; +} metadata; + +static xmlDocPtr g_doc; + +static int __create_engine_info_xml(const char *pkgid) +{ + LOGD("=== Create engine info doc"); + g_doc = xmlNewDoc((xmlChar*)"1.0"); + if (NULL == g_doc) { + LOGE("[ERROR] Fail to new doc"); + return -1; + } + LOGD("==="); + return 0; +} + +static int __save_engine_info_xml(const char *pkgid) +{ + LOGD("=== Save engine info doc"); + /* Make directories */ + if (0 != access(STT_CONFIG_BASE, F_OK)) { + if (0 != mkdir(STT_CONFIG_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", STT_CONFIG_BASE); + return -1; + } else { + LOGD("Success to make directory : %s", STT_CONFIG_BASE); + } + } + + if (0 != access(STT_HOME, F_OK)) { + if (0 != mkdir(STT_HOME, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", STT_HOME); + return -1; + } else { + LOGD("Success to make directory : %s", STT_HOME); + } + } + + if (0 != access(STT_ENGINE_BASE, F_OK)) { + if (0 != mkdir(STT_ENGINE_BASE, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", STT_ENGINE_BASE); + return -1; + } else { + LOGD("Success to make directory : %s", STT_ENGINE_BASE); + } + } + + if (0 != access(STT_ENGINE_INFO, F_OK)) { + if (0 != mkdir(STT_ENGINE_INFO, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { + LOGE("[ERROR] Fail to make directory : %s", STT_ENGINE_INFO); + return -1; + } else { + LOGD("Success to make directory : %s", STT_ENGINE_INFO); + } + } + + char path[256] = {'\0',}; + snprintf(path, 256, "%s/%s.xml", STT_ENGINE_INFO, pkgid); + int ret = xmlSaveFormatFile(path, g_doc, 1); + LOGD("xmlSaveFile (%d)", ret); + LOGD("==="); + return 0; +} + +static int __remove_engine_info_xml(const char *pkgid) +{ + LOGD("=== Remove engine info doc"); + char path[256] = {'\0',}; + snprintf(path, 256, "%s/%s.xml", STT_ENGINE_INFO, pkgid); + if (0 == access(path, F_OK)) { + LOGD("Remove engine info xml(%s)", path); + remove(path); + } + LOGD("==="); + return 0; +} + +static void __insert_language_from_metadata(xmlNodePtr root, const char *language) +{ + LOGD("==== Insert language"); + char* lang = NULL; + + char *tmp_lang, *tmp_free; + tmp_free = tmp_lang = strdup(language); + xmlNodePtr languages_node = NULL; + xmlNodePtr lang_node = NULL; + + languages_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_LANGUAGE_SET); + + lang = strsep(&tmp_lang, ","); + while(NULL != lang) { + LOGD("lang (%s)", lang); + lang_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_LANGUAGE); + xmlNodeSetContent(lang_node, (const xmlChar*)lang); + xmlAddChild(languages_node, lang_node); + lang = strsep(&tmp_lang, ","); + } + xmlAddChild(root, languages_node); + + free(tmp_free); +} + +EXPORT_API +int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgid, const char *appid, GList *list) +{ + LOGD("METADATA INSTALL"); + LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list)); + + uid_t uid = 0; + int ret = -1; + ret = pkgmgr_installer_info_get_target_uid(&uid); + if (ret < 0 ) { + LOGE("[ERROR] Fail to get target uid"); + return 0; + } else { + LOGD("uid(%d)", uid); + } + + ret = tzplatform_set_user(uid); + if (ret < 0) { + LOGE("[ERROR] Invalid uid"); + return 0; + } else { + LOGD("TZ_USER_HOME: %s", tzplatform_mkstr(TZ_USER_HOME, "/")); + } + + if (0 >= g_list_length(list)) { + LOGE("[ERROR] No Engine Metadata"); + return 0; + } + + GList *iter = NULL; + metadata *md = NULL; + + __create_engine_info_xml(pkgid); + + xmlNodePtr root = NULL; + xmlNodePtr cur = NULL; + + root = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_BASE); + if (NULL == root) { + LOGE("[ERROR] Fail to get new node"); + xmlFreeDoc(g_doc); + return -1; + } + xmlDocSetRootElement(g_doc, root); + + /* Save name */ + cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_NAME); + xmlNodeSetContent(cur, (const xmlChar*)pkgid); + xmlAddChild(root, cur); + + iter = g_list_first(list); + while (NULL != iter) { + md = (metadata *)iter->data; + if (NULL != md && NULL != md->key && NULL != md->value) { + LOGD(" - key(%s) value(%s)", md->key, md->value); + if (!strcmp(md->key, STT_METADATA_LANGUAGE)) { + __insert_language_from_metadata(root, md->value); + } else if (!strcmp(md->key, STT_METADATA_SILENCE_DETECTION)) { + cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_SILENCE_DETECTION_SUPPORT); + xmlNodeSetContent(cur, (const xmlChar*)md->value); + xmlAddChild(root, cur); + } else if (!strcmp(md->key, STT_METADATA_CREDENTIAL_REQUIRED)) { + cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_CREDENTIAL); + xmlNodeSetContent(cur, (const xmlChar*)md->value); + xmlAddChild(root, cur); + } else { + LOGW("[WARNING] Unknown metadata type"); + } + } + iter = g_list_next(iter); + } + + cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_ENGINE_ID); + xmlNodeSetContent(cur, (const xmlChar*)appid); + xmlAddChild(root, cur); + + LOGD(""); + + if (0 != __save_engine_info_xml(pkgid)) { + LOGE("[ERROR] Fail to make engine info file"); + return -1; + } + + xmlFreeDoc(g_doc); + + return 0; +} + +EXPORT_API +int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgid, const char *appid, GList *list) +{ + LOGD("METADATA UNINSTALL"); + LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list)); + + GList *iter = NULL; + metadata *md = NULL; + + iter = g_list_first(list); + while (NULL != iter) { + md = (metadata *)iter->data; + LOGD(" - key(%s) value(%s)", md->key, md->value); + iter = g_list_next(iter); + } + + __remove_engine_info_xml(pkgid); + + LOGD(""); + return 0; +} + +EXPORT_API +int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgid, const char *appid, GList *list) +{ + LOGD("METADATA UPGRADE"); + LOGD("pkgid(%s) appid(%s) list(%d)", pkgid, appid, g_list_length(list)); + + PKGMGR_MDPARSER_PLUGIN_UNINSTALL(pkgid, appid, list); + PKGMGR_MDPARSER_PLUGIN_INSTALL(pkgid, appid, list); + + LOGD(""); + return 0; +} diff --git a/packaging/stt.spec b/packaging/stt.spec index d74c63b..b5e2c6b 100644 --- a/packaging/stt.spec +++ b/packaging/stt.spec @@ -10,6 +10,7 @@ Source1002: %{name}-devel.manifest Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-media-audio-io) BuildRequires: pkgconfig(capi-media-wav-player) @@ -22,6 +23,9 @@ BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(pkgmgr) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(vconf) %if "%{PRODUCT_TYPE}" == "TV" BuildRequires: pkgconfig(capi-network-bluetooth) @@ -112,10 +116,12 @@ mkdir -p %{TZ_SYS_RO_SHARE}/voice/test %defattr(-,root,root,-) %{_libdir}/lib*.so /etc/dbus-1/session.d/stt-server.conf +%{TZ_SYS_RO_SHARE}/upgrade/scripts/500.stt_upgrade_24to30.sh %{TZ_SYS_RO_SHARE}/voice/stt/1.0/stt-config.xml %{TZ_SYS_RO_SHARE}/dbus-1/services/org.tizen.voice* %{TZ_SYS_RO_SHARE}/voice/test/stt-test %{TZ_SYS_RO_SHARE}/license/%{name} +%{TZ_SYS_RO_ETC}/package-manager/parserlib/metadata/libstt-engine-parser.so* %files devel %manifest %{name}-devel.manifest -- 2.7.4