-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
PROJECT(widget_service C CXX)
SET(PREFIX ${CMAKE_INSTALL_PREFIX})
SET(INCLUDEDIR "\${prefix}/include/${PROJECT_NAME}")
SET(VERSION ${FULLVER})
-set(CMAKE_SKIP_BUILD_RPATH true)
+SET(EXTRA_FLAGS "${EXTRA_FLAGS} -Wall")
+SET(EXTRA_FLAGS "${EXTRA_FLAGS} -Werror")
+SET(EXTRA_FLAGS "${EXTRA_FLAGS} -Wl,-zdefs")
+SET(EXTRA_FLAGS "${EXTRA_FLAGS} -fvisibility=hidden")
+SET(EXTRA_FLAGS "${EXTRA_FLAGS} -pthread")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_FLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAGS} -std=c++17")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
-INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED
- dlog
- glib-2.0
- gio-2.0
- sqlite3
- db-util
- pkgmgr-info
- vconf
- icu-uc
- bundle
- capi-base-common
- capi-system-info
- capi-appfw-app-common
- aul
- libtzplatform-config
- uuid
- cynara-client
- iniparser
- libsmack
-)
-
-FOREACH(flag ${pkgs_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-FOREACH(flag ${pkg_extra_CFLAGS})
- SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -g")
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-
-ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
-ADD_DEFINITIONS("-DLOG_TAG=\"WIDGET_SERVICE\"")
-ADD_DEFINITIONS("-DNDEBUG")
-ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET")
-ADD_DEFINITIONS("-DRESOLUTION_FILE=\"/usr/share/widget-service/resolution.ini\"")
-
-SET(BUILD_SOURCE
- src/widget_service.c
- src/widget_instance.c
-)
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${BUILD_SOURCE})
+## Target
+SET(TARGET_WIDGET_PARSER widget_parser)
+SET(TARGET_WIDGET_PARSER_PLUGIN widget-application)
+SET(TARGET_WIDGET_SERVICE widget_service)
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${MAJORVER})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${FULLVER})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${pkg_extra_LDFLAGS})
-
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-
-CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
-SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc")
-
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_service.h DESTINATION include/${PROJECT_NAME})
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_service_internal.h DESTINATION include/${PROJECT_NAME})
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_errno.h DESTINATION include/${PROJECT_NAME})
-INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/widget_instance.h DESTINATION include/${PROJECT_NAME})
-
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.resolution.ini DESTINATION /usr/share/${PROJECT_NAME} RENAME "mobile.resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.resolution.ini DESTINATION /usr/share/${PROJECT_NAME} RENAME "wearable.resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.320x480.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/320x480 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.480x800.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/480x800 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.360x480.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/360x480 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.360x360.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/360x360 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/720x1280 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/320x320 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.540x960.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/540x960 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.600x1024.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/600x1024 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.1080x1920.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1080x1920 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.1440x2560.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1440x2560 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.1440x3040.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1440x3040 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
-INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.common.1280x720.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1280x720 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")
+INCLUDE(FindPkgConfig)
+INCLUDE(ApplyPkgConfig)
+
+PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog)
+PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0)
+PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0)
+PKG_CHECK_MODULES(SQLITE3_DEPS REQUIRED sqlite3)
+PKG_CHECK_MODULES(DB_UTIL_DEPS REQUIRED db-util)
+PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info)
+PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf)
+PKG_CHECK_MODULES(ICU_UC_DEPS REQUIRED icu-uc)
+PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle)
+PKG_CHECK_MODULES(CAPI_BASE_COMMON_DEPS REQUIRED capi-base-common)
+PKG_CHECK_MODULES(CAPI_SYSTEM_INFO_DEPS REQUIRED capi-system-info)
+PKG_CHECK_MODULES(CAPI_APPFW_APP_COMMON_DEPS REQUIRED capi-appfw-app-common)
+PKG_CHECK_MODULES(AUL_DEPS REQUIRED aul)
+PKG_CHECK_MODULES(PLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
+PKG_CHECK_MODULES(UUID_DEPS REQUIRED uuid)
+PKG_CHECK_MODULES(CYNARA_CLIENT_DEPS REQUIRED cynara-client)
+PKG_CHECK_MODULES(INIPARSER_DEPS REQUIRED iniparser)
+PKG_CHECK_MODULES(SMACK_DEPS REQUIRED libsmack)
+PKG_CHECK_MODULES(XML_DEPS REQUIRED libxml-2.0)
+PKG_CHECK_MODULES(PKGMGR_INSTALLER_DEPS REQUIRED pkgmgr-installer)
+PKG_CHECK_MODULES(DATABASE_DEPS REQUIRED tizen-database)
+
+ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(parser)
ADD_SUBDIRECTORY(tool)
ADD_SUBDIRECTORY(unittest)
SET(WIDGET_SERVICE_UNIT_TESTS widget_service_unittests)
ADD_TEST(NAME ${WIDGET_SERVICE_UNIT_TESTS} COMMAND ${WIDGET_SERVICE_UNIT_TESTS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/unittest)
-
-# End of a file
--- /dev/null
+# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+#
+# This function applies external (out of source tree) dependencies
+# to given target. Arguments are:
+# TARGET - valid cmake target
+# PRIVACY - dependency can be inherited by dependent targets or not:
+# PUBLIC - this should be used by default, cause compile/link flags passing
+# PRIVATE - do not passes any settings to dependent targets,
+# may be usefull for static libraries from the inside of the project
+# Argument ARGV2 and following are supposed to be names of checked pkg config
+# packages. This function will use variables created by check_pkg_modules().
+# - ${DEP_NAME}_LIBRARIES
+# - ${DEP_NAME}_INCLUDE_DIRS
+# - ${DEP_NAME}_CFLAGS
+#
+FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
+ MATH(EXPR DEST_INDEX "${ARGC}-1")
+ FOREACH(I RANGE 2 ${DEST_INDEX})
+ IF(NOT ${ARGV${I}}_FOUND)
+ MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND")
+ ENDIF(NOT ${ARGV${I}}_FOUND)
+ TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}")
+ TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}")
+ STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}")
+ SET(CFLAGS_LIST ${CFLAGS_STR})
+ SEPARATE_ARGUMENTS(CFLAGS_LIST)
+ FOREACH(OPTION ${CFLAGS_LIST})
+ TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION})
+ ENDFOREACH(OPTION)
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true)
+ ENDFOREACH(I RANGE 2 ${DEST_INDEX})
+ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY)
BuildRequires: pkgconfig(iniparser)
BuildRequires: pkgconfig(libsmack)
BuildRequires: pkgconfig(gmock)
+BuildRequires: pkgconfig(tizen-database)
%if 0%{?gcov:1}
BuildRequires: lcov
%description devel
Gathering the installed widget information.
+%package -n widget-service-parser-devel
+Summary: Widget element parser library
+Group: Application Framework/Service
+
+%description -n widget-service-parser-devel
+This module is for making a widget parser plugin
+
#################################################
# widget_service_gcov
#################################################
%__make %{?jobs:-j%jobs}
%check
+export LD_LIBRARY_PATH="../parser/lib:../src"
ctest -V
%if 0%{?gcov:1}
lcov -c --ignore-errors graph --no-external -q -d . -o widget_service.info
%defattr(-,root,root,-)
%license LICENSE
%{_libdir}/libwidget_service.so.*
+%{_libdir}/libwidget_parser.so.*
%{_sysconfdir}/package-manager/parserlib/libwidget-application.so
%{_sysconfdir}/skel/.applications/dbspace/.widget.db
%{_sysconfdir}/skel/.applications/dbspace/.widget.db-journal
%{_datadir}/gcov/obj/*
%endif
-# End of a file
+%files -n widget-service-parser-devel
+%defattr(-,root,root,-)
+%license LICENSE
+%{_includedir}/widget_parser/*
+%{_libdir}/pkgconfig/widget-service-parser.pc
+%{_libdir}/libwidget_parser.so
-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
- pkgmgr-installer
- )
-FOREACH(FLAGS ${PKGS_CFLAGS})
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
-ENDFOREACH(FLAGS)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fPIC")
-
-SET(PLUGINS_LIST_FILE_NAME widget.info)
-SET(PLUGINS_LIST_FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGINS_LIST_FILE_NAME})
-SET(PLUGINS_LIST_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/share/parser-plugins)
-ADD_DEFINITIONS("-DPLUGINS_LIST_INSTALL_PATH=\"${PLUGINS_LIST_INSTALL_PATH}\"")
-INSTALL(FILES ${PLUGINS_LIST_FILE_PATH} DESTINATION ${PLUGINS_LIST_INSTALL_PATH}/)
-
-ADD_LIBRARY(widget-application MODULE ${SRCS})
-
-INSTALL(TARGETS widget-application DESTINATION ${SYSCONF_INSTALL_DIR}/package-manager/parserlib/)
+ADD_SUBDIRECTORY(lib)
+ADD_SUBDIRECTORY(installer_plugin)
\ No newline at end of file
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} LIB_SRCS)
+ADD_LIBRARY(${TARGET_WIDGET_PARSER_PLUGIN} MODULE ${LIB_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_PARSER_PLUGIN} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
+
+TARGET_LINK_LIBRARIES(${TARGET_WIDGET_PARSER_PLUGIN} PRIVATE ${TARGET_WIDGET_PARSER} "-ldl")
+
+APPLY_PKG_CONFIG(${TARGET_WIDGET_PARSER_PLUGIN} PUBLIC
+ GLIB_DEPS
+ SQLITE3_DEPS
+ XML_DEPS
+ DLOG_DEPS
+ PLATFORM_CONFIG_DEPS
+ PKGMGR_INSTALLER_DEPS
+)
+
+SET(PLUGINS_LIST_FILE_NAME widget.info)
+SET(PLUGINS_LIST_FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGINS_LIST_FILE_NAME})
+SET(PLUGINS_LIST_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/share/parser-plugins)
+ADD_DEFINITIONS("-DPLUGINS_LIST_INSTALL_PATH=\"${PLUGINS_LIST_INSTALL_PATH}\"")
+INSTALL(FILES ${PLUGINS_LIST_FILE_PATH} DESTINATION ${PLUGINS_LIST_INSTALL_PATH}/)
+
+INSTALL(TARGETS ${TARGET_WIDGET_PARSER_PLUGIN} DESTINATION ${SYSCONF_INSTALL_DIR}/package-manager/parserlib/)
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <dlfcn.h>
+#include <glib.h>
+#include <libxml/tree.h>
+#include <dlog.h>
+#include <unistd.h>
+
+#include "widget_plugin_parser_error.h"
+#include "widget_plugin_parser_log.h"
+#include "widget_plugin_parser.hh"
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+using namespace widget_service::parser;
+
+namespace {
+
+constexpr const char PLUGIN_PATH[] =
+ "/usr/share/widget-service/plugin/widget-service-parser-plugin.so";
+
+struct DlCloser {
+ void operator()(void* handle) const {
+ dlclose(handle);
+ }
+};
+
+std::unique_ptr<void, DlCloser> g_plugin;
+
+IWidgetPluginParser* LoadPlugin() {
+ static IWidgetPluginParser* parser;
+
+ if (parser)
+ return parser;
+
+ if (access(PLUGIN_PATH, F_OK) == -1) {
+ LOGD("%s does not exist", PLUGIN_PATH);
+ return nullptr;
+ }
+
+ g_plugin.reset(dlopen(PLUGIN_PATH, RTLD_LAZY | RTLD_GLOBAL));
+ if (!g_plugin) {
+ LOGE("dlopen() is failed. path(%s), error(%s)", PLUGIN_PATH,
+ dlerror());
+ return nullptr;
+ }
+
+ using parser_func = IWidgetPluginParser* (*)();
+ auto* get_mod = reinterpret_cast<parser_func>(
+ dlsym(g_plugin.get(), "WIDGET_SERVICE_PARSER_GET_INTERFACE"));
+ if (get_mod == nullptr) {
+ LOGE("dlsym() is failed");
+ return nullptr;
+ }
+
+ parser = get_mod();
+
+ return parser;
+}
+
+IWidgetPluginParser* GetPlugin() {
+ auto* ret = LoadPlugin();
+
+ if (ret)
+ return ret;
+
+ return new WidgetPluginParser();
+}
+
+} // namespace
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char* pkgid) {
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc,
+ const char* pkgid) {
+ std::unique_ptr<IWidgetPluginParser> parser(GetPlugin());
+
+ int ret = parser->ParseManifest(doc);
+ if (ret == WIDGET_PARSER_ERROR_NOT_EXIST) {
+ LOGW("not exist");
+ return 0;
+ }
+
+ if (ret != WIDGET_PARSER_ERROR_NONE) {
+ LOGE("parse failed");
+ return -1;
+ }
+
+ if (parser->Insert(pkgid))
+ return -1;
+
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char* pkgid) {
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char* pkgid) {
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc,
+ const char* pkgid) {
+ std::unique_ptr<IWidgetPluginParser> parser(GetPlugin());
+
+ int ret = parser->ParseManifest(doc);
+ if (ret == WIDGET_PARSER_ERROR_NOT_EXIST) {
+ LOGW("not exist");
+ return 0;
+ }
+
+ if (ret != WIDGET_PARSER_ERROR_NONE) {
+ LOGE("parse failed");
+ return -1;
+ }
+
+ if (parser->Remove(pkgid))
+ return -1;
+
+ if (parser->Insert(pkgid))
+ return -1;
+
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char* pkgid) {
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char* pkgid) {
+ return 0;
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc,
+ const char* pkgid) {
+ std::unique_ptr<IWidgetPluginParser> parser(GetPlugin());
+ return parser->Remove(pkgid);
+}
+
+extern "C" API int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char* pkgid) {
+ return 0;
+}
--- /dev/null
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} LIB_SRCS)
+ADD_LIBRARY(${TARGET_WIDGET_PARSER} SHARED ${LIB_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_PARSER} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_PARSER} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_PARSER} PROPERTIES OUTPUT_NAME widget_parser)
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_PARSER} PROPERTIES COMPILE_FLAGS
+ ${CFLAGS} "-fpic")
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_PARSER} PROPERTIES LINK_FLAGS "-ldl -lpthread")
+
+APPLY_PKG_CONFIG(${TARGET_WIDGET_PARSER} PUBLIC
+ GLIB_DEPS
+ SQLITE3_DEPS
+ XML_DEPS
+ DLOG_DEPS
+ PLATFORM_CONFIG_DEPS
+ PKGMGR_INSTALLER_DEPS
+ PKGMGR_INFO_DEPS
+ DATABASE_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_WIDGET_PARSER} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/widget_parser
+ FILES_MATCHING
+ PATTERN "*_impl.hh" EXCLUDE
+ PATTERN "*.hh")
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/widget-service-parser.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+CONFIGURE_FILE(widget-service-parser.pc.in widget-service-parser.pc @ONLY)
+SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "widget-service-parser.pc")
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+
+#ifndef WIDGET_SERVICE_PARSER_LIB_I_WIDGET_PLUGIN_PARSER_HH_
+#define WIDGET_SERVICE_PARSER_LIB_I_WIDGET_PLUGIN_PARSER_HH_
+
+#include <libxml/tree.h>
+
+#include <string>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace widget_service::parser {
+
+class EXPORT_API IWidgetPluginParser {
+ public:
+ virtual ~IWidgetPluginParser() = default;
+
+ virtual int ParseManifest(xmlDocPtr doc) = 0;
+ virtual int Insert(const std::string& pkgid) = 0;
+ virtual int Remove(const std::string& pkgid) = 0;
+};
+
+} // namespace widget_service::parser
+
+#endif // WIDGET_SERVICE_PARSER_LIB_I_WIDGET_PLUGIN_PARSER_HH_
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: widget_parser
+Description: widget parser library
+Version: @VERSION@
+Requires: widget_service
+Libs: -L${libdir} -lwidget_parser
+Cflags: -I${includedir}
+cppflags: -I${includedir}
--- /dev/null
+/*
+ * Copyright (c) 2022 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 "widget_info.hh"
+
+namespace widget_service::parser {
+
+WidgetInfo::SupportSize::SupportSize(std::string preview, bool frame,
+ int width, int height)
+ : preview_(std::move(preview)), frame_(frame), width_(width),
+ height_(height) {
+}
+
+const std::string& WidgetInfo::SupportSize::GetPreview() const {
+ return preview_;
+}
+
+bool WidgetInfo::SupportSize::IsFrame() const {
+ return frame_;
+}
+
+int WidgetInfo::SupportSize::GetWidth() const {
+ return width_;
+}
+
+int WidgetInfo::SupportSize::GetHeight() const {
+ return height_;
+}
+
+WidgetInfo::Label::Label(std::string label, std::string lang)
+ : label_(std::move(label)), lang_(std::move(lang)) {
+}
+
+const std::string& WidgetInfo::Label::GetLabel() const {
+ return label_;
+}
+
+const std::string& WidgetInfo::Label::GetLang() const {
+ return lang_;
+}
+
+WidgetInfo::Icon::Icon(std::string icon, std::string lang)
+ : icon_(std::move(icon)), lang_(std::move(lang)) {
+}
+
+const std::string& WidgetInfo::Icon::GetIcon() const {
+ return icon_;
+}
+
+const std::string& WidgetInfo::Icon::GetLang() const {
+ return lang_;
+}
+
+WidgetInfo::WidgetInfo(std::string class_id, int update_period,
+ std::string setup_appid, std::string appid, int max_instance,
+ int nodisplay, int prime,
+ std::list<WidgetInfo::SupportSize> support_size_list,
+ std::list<WidgetInfo::Label> label_list,
+ std::list<WidgetInfo::Icon> icon_list)
+ : class_id_(std::move(class_id)), update_period_(update_period),
+ setup_appid_(std::move(setup_appid)), appid_(std::move(appid)),
+ max_instance_(max_instance), nodisplay_(nodisplay), prime_(prime),
+ support_size_list_(std::move(support_size_list)),
+ label_list_(std::move(label_list)), icon_list_(std::move(icon_list)) {
+}
+
+const std::string& WidgetInfo::GetClassId() const {
+ return class_id_;
+}
+
+int WidgetInfo::GetUpdatePeriod() const {
+ return update_period_;
+}
+
+const std::string& WidgetInfo::GetSetupAppId() const {
+ return setup_appid_;
+}
+
+const std::string& WidgetInfo::GetAppId() const {
+ return appid_;
+}
+
+int WidgetInfo::GetMaxInstance() const {
+ return max_instance_;
+}
+
+int WidgetInfo::GetNoDisplay() const {
+ return nodisplay_;
+}
+
+int WidgetInfo::GetPrime() const {
+ return prime_;
+}
+
+const std::list<WidgetInfo::SupportSize>&
+WidgetInfo::GetSupportSizeList() const {
+ return support_size_list_;
+}
+
+const std::list<WidgetInfo::Label>&
+WidgetInfo::GetLabelList() const {
+ return label_list_;
+}
+
+const std::list<WidgetInfo::Icon>& WidgetInfo::GetIconList() const {
+ return icon_list_;
+}
+
+} // namespace widget_service::parser
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+#ifndef WIDGET_SERVICE_PARSER_WIDGET_INFO_HH_
+#define WIDGET_SERVICE_PARSER_WIDGET_INFO_HH_
+
+#include <list>
+#include <string>
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace widget_service::parser {
+
+class EXPORT_API WidgetInfo {
+ public:
+ class SupportSize {
+ public:
+ SupportSize() = default;
+ SupportSize(std::string preview, bool frame, int width, int height);
+
+ const std::string& GetPreview() const;
+ bool IsFrame() const;
+ int GetWidth() const;
+ int GetHeight() const;
+
+ private:
+ std::string preview_;
+ bool frame_ = false;
+ int width_ = 0;
+ int height_ = 0;
+ };
+
+ class Label {
+ public:
+ Label() = default;
+ Label(std::string label, std::string lang);
+
+ const std::string& GetLabel() const;
+ const std::string& GetLang() const;
+
+ private:
+ std::string label_;
+ std::string lang_;
+ };
+
+ class Icon {
+ public:
+ Icon() = default;
+ Icon(std::string icon, std::string lang);
+
+ const std::string& GetIcon() const;
+ const std::string& GetLang() const;
+
+ private:
+ std::string icon_;
+ std::string lang_;
+ };
+
+ WidgetInfo(std::string class_id, int update_period,
+ std::string setup_appid, std::string appid, int max_instance,
+ int nodisplay, int prime, std::list<SupportSize> support_size_list,
+ std::list<Label> label_list, std::list<Icon> icon_list);
+
+ const std::string& GetClassId() const;
+ int GetUpdatePeriod() const;
+ const std::string& GetSetupAppId() const;
+ const std::string& GetAppId() const;
+ int GetMaxInstance() const;
+ int GetNoDisplay() const;
+ int GetPrime() const;
+ const std::list<SupportSize>& GetSupportSizeList() const;
+ const std::list<Label>& GetLabelList() const;
+ const std::list<Icon>& GetIconList() const;
+
+ private:
+ std::string class_id_;
+ int update_period_ = 0;
+ std::string setup_appid_;
+ std::string appid_;
+ int max_instance_ = 0;
+ int nodisplay_ = 0;
+ int prime_ = 0;
+ std::list<SupportSize> support_size_list_;
+ std::list<Label> label_list_;
+ std::list<Icon> icon_list_;
+};
+
+} // namespace widget_service::parser
+
+#endif // WIDGET_SERVICE_PARSER_WIDGET_INFO_HH_
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <sys/types.h>
+#include <libxml/tree.h>
+#include <glib.h>
+
+#include <map>
+#include <string>
+
+#include "widget_plugin_parser_error.h"
+#include "widget_plugin_parser_log.h"
+#include "widget_plugin_parser_impl.hh"
+
+namespace {
+
+enum widget_tag {
+ TAG_WIDGET_APPLICATION = 1,
+ TAG_COMPONENT_BASED_APPLICATION,
+ TAG_WIDGET_COMPONENT,
+ TAG_WIDGET_CLASS,
+ TAG_LABEL,
+ TAG_ICON,
+ TAG_SUPPORT_SIZE,
+};
+
+std::map<std::string, widget_tag> tag_map = {
+ { "widget-application", TAG_WIDGET_APPLICATION },
+ { "component-based-application", TAG_COMPONENT_BASED_APPLICATION },
+ { "widget-component", TAG_WIDGET_COMPONENT },
+ { "widget-class", TAG_WIDGET_CLASS },
+ { "label", TAG_LABEL },
+ { "icon", TAG_ICON },
+ { "support-size", TAG_SUPPORT_SIZE }
+};
+
+std::string GetAttribute(xmlNode* node, const char* name) {
+ xmlChar* val = xmlGetProp(node, (const xmlChar*)name);
+ if (val) {
+ return std::string(reinterpret_cast<const char*>(val));
+ xmlFree(val);
+ }
+
+ return "";
+}
+
+enum widget_tag GetTag(xmlNode* node) {
+ return tag_map[std::string(reinterpret_cast<const char*>(node->name))];
+}
+
+} // namespace
+
+namespace widget_service::parser {
+
+WidgetPluginParser::WidgetPluginParser()
+ : impl_(std::make_unique<WidgetPluginParser::Impl>()) {
+}
+
+WidgetPluginParser::~WidgetPluginParser() = default;
+
+int WidgetPluginParser::ParseManifest(xmlDocPtr doc) {
+ if (doc == nullptr) {
+ LOGE("invalid parameter");
+ return WIDGET_PARSER_ERROR_INVALID_PARAMETER;
+ }
+
+ impl_->info_list_.clear();
+ xmlNode* root = xmlDocGetRootElement(doc);
+ if (root == nullptr) {
+ LOGE("failed to get root element");
+ return WIDGET_PARSER_ERROR_INVALID_PARAMETER;
+ }
+
+ for (xmlNode* tmp = root->children; tmp; tmp = tmp->next) {
+ switch (GetTag(tmp)) {
+ case TAG_WIDGET_APPLICATION:
+ if (ParseWidgetApplication(tmp)) {
+ LOGE("parse failed");
+ return WIDGET_PARSER_ERROR_IO_ERROR;
+ }
+ break;
+ case TAG_COMPONENT_BASED_APPLICATION:
+ for (xmlNode* tmp_comp = tmp->children; tmp_comp;
+ tmp_comp = tmp_comp->next) {
+ if (GetTag(tmp_comp) != TAG_WIDGET_COMPONENT)
+ continue;
+
+ std::string appid = GetAttribute(tmp, "appid");
+ if (appid.empty())
+ return WIDGET_PARSER_ERROR_IO_ERROR;
+
+ if (ParseWidgetComponent(tmp_comp, appid)) {
+ LOGE("parse failed");
+ return WIDGET_PARSER_ERROR_IO_ERROR;
+ }
+ }
+ break;
+ default:
+ continue;
+ }
+ }
+
+ if (impl_->info_list_.empty())
+ return WIDGET_PARSER_ERROR_NOT_EXIST;
+
+ return WIDGET_PARSER_ERROR_NONE;
+}
+
+int WidgetPluginParser::ParseWidgetComponent(xmlNode* node,
+ const std::string& appid) {
+ std::list<WidgetInfo::SupportSize> support_size_list;
+ std::list<WidgetInfo::Label> label_list;
+ std::list<WidgetInfo::Icon> icon_list;
+ int update_period = 0;
+ int nodisplay = 0;
+ int max_instance = 0;
+ int prime = 0;
+
+ std::string val = GetAttribute(node, "id");
+ if (val.empty())
+ return -1;
+
+ std::string class_id = val + "@" + appid;
+ val = GetAttribute(node, "update-period");
+ if (!val.empty())
+ update_period = atoi(val.c_str());
+
+ val = GetAttribute(node, "icon-display");
+ if (val == "true")
+ nodisplay = 1;
+ else
+ nodisplay = 0;
+
+ std::string setup_appid = GetAttribute(node, "setup-appid");
+ val = GetAttribute(node, "max-instance");
+ if (!val.empty())
+ max_instance = atoi(val.c_str());
+
+ val = GetAttribute(node, "main");
+ if (val == "true")
+ prime = 1;
+ else
+ prime = 0;
+
+ for (xmlNode* tmp = node->children; tmp; tmp = tmp->next) {
+ switch (GetTag(tmp)) {
+ case TAG_SUPPORT_SIZE:
+ if (ParseSupportSize(tmp, support_size_list))
+ return -1;
+ break;
+ case TAG_ICON:
+ if (ParseIcon(tmp, icon_list))
+ return -1;
+ break;
+ case TAG_LABEL:
+ if (ParseLabel(tmp, label_list))
+ return -1;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ impl_->info_list_.emplace_back(std::move(class_id), update_period,
+ std::move(setup_appid), appid,
+ max_instance, nodisplay, prime, std::move(support_size_list),
+ std::move(label_list), std::move(icon_list));
+
+ return 0;
+}
+
+int WidgetPluginParser::ParseWidgetApplication(xmlNode* node) {
+ int update_period = 0;
+ int max_instance = 0;
+ int nodisplay = 0;
+ int prime = 0;
+ std::list<WidgetInfo::SupportSize> support_size_list;
+ std::list<WidgetInfo::Label> label_list;
+ std::list<WidgetInfo::Icon> icon_list;
+
+ std::string val = GetAttribute(node, "appid");
+ if (val.empty())
+ return -1;
+
+ std::string appid = val;
+ std::string class_id = appid;
+
+ val = GetAttribute(node, "update-period");
+ if (!val.empty())
+ update_period = atoi(val.c_str());
+
+ val = GetAttribute(node, "nodisplay");
+ if (val == "true")
+ nodisplay = 1;
+ else
+ nodisplay = 0;
+
+ std::string setup_appid = GetAttribute(node, "setup-appid");
+
+ val = GetAttribute(node, "max-instance");
+ if (!val.empty())
+ max_instance = atoi(val.c_str());
+
+ val = GetAttribute(node, "main");
+ if (val == "true")
+ prime = 1;
+ else
+ prime = 0;
+
+ for (xmlNode* tmp = node->children; tmp; tmp = tmp->next) {
+ switch (GetTag(tmp)) {
+ case TAG_SUPPORT_SIZE:
+ if (ParseSupportSize(tmp, support_size_list))
+ return -1;
+ break;
+ case TAG_ICON:
+ if (ParseIcon(tmp, icon_list))
+ return -1;
+ break;
+ case TAG_LABEL:
+ if (ParseLabel(tmp, label_list))
+ return -1;
+ break;
+ case TAG_WIDGET_CLASS:
+ if (ParseWidgetClass(tmp, appid))
+ return -1;
+ default:
+ continue;
+ }
+ }
+
+ impl_->info_list_.emplace_back(std::move(class_id), update_period,
+ std::move(setup_appid), appid,
+ max_instance, nodisplay, prime, std::move(support_size_list),
+ std::move(label_list), std::move(icon_list));
+
+ return 0;
+}
+
+int WidgetPluginParser::ParseWidgetClass(xmlNode* node,
+ const std::string& appid) {
+ int update_period = 0;
+ int max_instance = 0;
+ std::list<WidgetInfo::SupportSize> support_size_list;
+ std::list<WidgetInfo::Label> label_list;
+ std::list<WidgetInfo::Icon> icon_list;
+
+ std::string val = GetAttribute(node, "classid");
+ if (val.empty())
+ return -1;
+
+ std::string class_id = val + "@" + appid;
+ val = GetAttribute(node, "update-period");
+ if (!val.empty())
+ update_period = atoi(val.c_str());
+
+ std::string setup_appid = GetAttribute(node, "setup-appid");
+ val = GetAttribute(node, "max-instance");
+ if (!val.empty())
+ max_instance = atoi(val.c_str());
+
+ for (xmlNode* tmp = node->children; tmp; tmp = tmp->next) {
+ switch (GetTag(tmp)) {
+ case TAG_SUPPORT_SIZE:
+ if (ParseSupportSize(tmp, support_size_list))
+ return -1;
+ break;
+ case TAG_ICON:
+ if (ParseIcon(tmp, icon_list))
+ return -1;
+ break;
+ case TAG_LABEL:
+ if (ParseLabel(tmp, label_list))
+ return -1;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ impl_->info_list_.emplace_back(std::move(class_id), update_period,
+ std::move(setup_appid), appid,
+ max_instance, 0, 0, std::move(support_size_list),
+ std::move(label_list), std::move(icon_list));
+
+ return 0;
+}
+
+int WidgetPluginParser::ParseSupportSize(xmlNode* node,
+ std::list<WidgetInfo::SupportSize>& sizes) {
+ char* val;
+ char* tok;
+ char* ptr;
+
+ if (node->children == nullptr || node->children->content == nullptr)
+ return -1;
+
+ val = strdup((char *)node->children->content);
+ tok = strtok_r(val, "xX", &ptr);
+ if (tok == nullptr) {
+ free(val);
+ return -1;
+ }
+
+ int width = atoi(tok);
+ tok = strtok_r(nullptr, "xX", &ptr);
+ if (tok == nullptr) {
+ free(val);
+ return -1;
+ }
+
+ int height = atoi(tok);
+ free(val);
+
+ std::string preview = GetAttribute(node, "preview");
+ std::string attr = GetAttribute(node, "frame");
+ bool frame = false;
+ if (!attr.empty() && !strcasecmp(attr.c_str(), "true"))
+ frame = true;
+
+ sizes.emplace_back(std::move(preview), frame, width, height);
+
+ return 0;
+}
+
+int WidgetPluginParser::ParseIcon(xmlNode* node,
+ std::list<WidgetInfo::Icon>& icons) {
+ if (node->children == nullptr || node->children->content == nullptr)
+ return -1;
+
+ std::string icon = reinterpret_cast<const char*>(node->children->content);
+ std::string lang = GetAttribute(node, "lang");
+
+ icons.emplace_back(std::move(icon), std::move(lang));
+
+ return 0;
+}
+
+int WidgetPluginParser::ParseLabel(xmlNode* node,
+ std::list<WidgetInfo::Label>& labels) {
+ if (node->children == nullptr || node->children->content == nullptr)
+ return -1;
+
+ std::string label = reinterpret_cast<const char*>(node->children->content);
+ std::string lang = GetAttribute(node, "lang");
+
+ labels.emplace_back(std::move(label), std::move(lang));
+
+ return 0;
+}
+
+std::list<WidgetInfo>& WidgetPluginParser::GetWidgetInfoList() {
+ return impl_->info_list_;
+}
+
+} // namespace widget_service::parser
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+
+#ifndef WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_HH
+#define WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_HH
+
+#include <libxml/tree.h>
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "i_widget_plugin_parser.hh"
+#include "widget_info.hh"
+
+#undef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+
+namespace widget_service::parser {
+
+class EXPORT_API WidgetPluginParser : public IWidgetPluginParser {
+ public:
+ WidgetPluginParser();
+ virtual ~WidgetPluginParser();
+
+ int ParseManifest(xmlDocPtr doc) override;
+ int Insert(const std::string& pkgid) override;
+ int Remove(const std::string& pkgid) override;
+ std::list<WidgetInfo>& GetWidgetInfoList();
+
+ protected:
+ virtual int ParseWidgetComponent(xmlNode* node, const std::string& appid);
+ virtual int ParseWidgetApplication(xmlNode* node);
+ virtual int ParseWidgetClass(xmlNode* node, const std::string& appid);
+ virtual int ParseSupportSize(xmlNode* node,
+ std::list<WidgetInfo::SupportSize>& sizes);
+ virtual int ParseIcon(xmlNode* node, std::list<WidgetInfo::Icon>& icons);
+ virtual int ParseLabel(xmlNode* node, std::list<WidgetInfo::Label>& labels);
+
+ private:
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+};
+
+} // namespace widget_service::parser
+
+#endif // WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_HH
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <unistd.h>
+#include <sys/types.h>
+#include <linux/limits.h>
+#include <glib.h>
+#include <dlog.h>
+#include <tzplatform_config.h>
+#include <pkgmgr-info.h>
+#include <pkgmgr_installer_info.h>
+
+#include "widget_plugin_parser_log.h"
+#include "widget_plugin_parser_impl.hh"
+
+#define GLOBALAPP_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+namespace {
+
+int target_uid_initialized;
+uid_t target_uid;
+int root_path_initialized;
+std::string root_path;
+
+uid_t GetTargetUid() {
+ if (target_uid_initialized)
+ return target_uid;
+
+ int ret = pkgmgr_installer_info_get_target_uid(&target_uid);
+ if (ret < 0)
+ LOGE("Failed to get target uid - %d", ret);
+
+ target_uid_initialized = 1;
+
+ return target_uid;
+}
+
+const std::string& GetRootPath(const char* pkgid) {
+ pkgmgrinfo_pkginfo_h pkginfo;
+ char* path = nullptr;
+ uid_t uid = GetTargetUid();
+ static std::string empty;
+
+ if (root_path_initialized)
+ return root_path;
+
+ int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
+ if (ret != PMINFO_R_OK) {
+ LOGE("Failed to get pkginfo - %d(%s)", ret, pkgid);
+ return empty;
+ }
+
+ ret = pkgmgrinfo_pkginfo_get_root_path(pkginfo, &path);
+ if (ret != PMINFO_R_OK) {
+ LOGE("Failed to get root path - %d(%s)", ret, pkgid);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
+ return empty;
+ }
+
+ root_path = path ? path : "./";
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
+ root_path_initialized = 1;
+
+ return root_path;
+}
+
+std::string ConvertPath(const std::string& preview_path,
+ const std::string& pkgid) {
+ if (!preview_path.empty()) {
+ if (preview_path[0] == '/') {
+ return preview_path;
+ } else {
+ return GetRootPath(pkgid.c_str()) + "/shared/res/" + preview_path;
+ }
+ }
+
+ return "";
+}
+
+bool BusyHandler(int count) {
+ constexpr int BUSY_WAITING_USEC = 50000;
+ constexpr int BUSY_WAITING_MAX = 20;
+
+ if (count < BUSY_WAITING_MAX) {
+ usleep(BUSY_WAITING_USEC);
+ return true;
+ }
+
+ return false;
+}
+
+int IsGlobal(uid_t uid) {
+ constexpr int ROOT_USER = 0;
+
+ if (uid == ROOT_USER || uid == GLOBALAPP_USER)
+ return 1;
+ else
+ return 0;
+}
+
+const char* GetDbPath(uid_t uid) {
+ if (!IsGlobal(uid))
+ tzplatform_set_user(uid);
+
+ const char* path = tzplatform_mkpath(IsGlobal(uid) ?
+ TZ_SYS_DB : TZ_USER_DB, ".widget.db");
+
+ tzplatform_reset_user();
+
+ return path;
+}
+
+} // namespace
+
+namespace widget_service::parser {
+
+int WidgetPluginParser::Insert(const std::string& pkgid) {
+ std::string path = GetDbPath(GetTargetUid());
+
+ if (access(path.c_str(), F_OK) == -1) {
+ LOGD("db(%s) does not exist, create one", path.c_str());
+ return -1;
+ }
+
+ try {
+ tizen_base::Database db(path, SQLITE_OPEN_READWRITE, BusyHandler);
+ auto r = db.Exec({ "PRAGMA foreign_keys = ON" });
+ if (!static_cast<bool>(r)) {
+ LOGE("Failed to set foreign key");
+ return -1;
+ }
+
+ auto guard = db.CreateTransactionGuard();
+ int ret = impl_->InsertWidgetClass(db, pkgid);
+ if (ret) {
+ LOGE("failed to insert widget class data");
+ return -1;
+ }
+
+ guard.Commit();
+ } catch (const tizen_base::DbException& e) {
+ LOGE("Catch : %s", e.msg());
+ return -1;
+ }
+ return 0;
+}
+
+int WidgetPluginParser::Remove(const std::string& pkgid) {
+ std::string path = GetDbPath(GetTargetUid());
+
+ if (access(path.c_str(), F_OK) == -1) {
+ LOGD("db(%s) does not exist, create one", path.c_str());
+ return -1;
+ }
+
+ try {
+ tizen_base::Database db(path, SQLITE_OPEN_READWRITE, BusyHandler);
+ auto r = db.Exec({ "PRAGMA foreign_keys = ON" });
+ if (!static_cast<bool>(r)) {
+ LOGE("Failed to set foreign key");
+ return -1;
+ }
+
+ auto guard = db.CreateTransactionGuard();
+ int ret = impl_->RemoveWidgetClass(db, pkgid);
+ if (ret) {
+ LOGE("failed to insert widget class data");
+ return -1;
+ }
+
+ guard.Commit();
+ } catch (const tizen_base::DbException& e) {
+ LOGE("Catch : %s", e.msg());
+ return -1;
+ }
+
+ return 0;
+}
+
+int WidgetPluginParser::Impl::InsertWidgetClass(const tizen_base::Database& db,
+ const std::string& pkgid) {
+ for (const auto& i : info_list_) {
+ auto q = tizen_base::Database::Sql(
+ "INSERT OR REPLACE INTO widget_class (classid, update_period, "
+ "setup_appid, appid, pkgid, nodisplay, max_instance, prime) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
+ .SetEmptyStringAsNull(true)
+ .Bind(i.GetClassId())
+ .Bind(i.GetUpdatePeriod())
+ .Bind(i.GetSetupAppId())
+ .Bind(i.GetAppId())
+ .Bind(pkgid)
+ .Bind(i.GetNoDisplay())
+ .Bind(i.GetMaxInstance())
+ .Bind(i.GetPrime());
+ auto r = db.Exec(q);
+ if (!static_cast<bool>(r))
+ return -1;
+
+ if (InsertSupportSize(db, pkgid, i.GetClassId(),
+ i.GetSupportSizeList())) {
+ LOGE("Failed to insert support size");
+ return -1;
+ }
+
+ if (InsertLabel(db, i.GetClassId(), i.GetLabelList())) {
+ LOGE("Failed to insert label");
+ return -1;
+ }
+
+ if (InsertIcon(db, pkgid, i.GetClassId(), i.GetIconList())) {
+ LOGE("Failed to insert icon");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int WidgetPluginParser::Impl::RemoveWidgetClass(const tizen_base::Database& db,
+ const std::string& pkgid) {
+ auto q = tizen_base::Database::Sql(
+ "DELETE FROM widget_class WHERE pkgid=?")
+ .SetEmptyStringAsNull(true)
+ .Bind(pkgid);
+
+ auto r = db.Exec(q);
+ if (!static_cast<bool>(r))
+ return -1;
+
+ return 0;
+}
+
+int WidgetPluginParser::Impl::InsertSupportSize(const tizen_base::Database& db,
+ const std::string& pkgid, const std::string& classid,
+ const std::list<WidgetInfo::SupportSize>& sizes) {
+ for (const auto& i : sizes) {
+ auto q = tizen_base::Database::Sql(
+ "INSERT OR REPLACE INTO support_size "
+ "(classid, preview, frame, width, height) "
+ "VALUES (?, ?, ?, ?, ?)")
+ .SetEmptyStringAsNull(true)
+ .Bind(classid)
+ .Bind(ConvertPath(i.GetPreview(), pkgid))
+ .Bind(i.IsFrame() ? 1 : 0)
+ .Bind(i.GetWidth())
+ .Bind(i.GetHeight());
+ auto r = db.Exec(q);
+ if (!static_cast<bool>(r))
+ return -1;
+ }
+
+ return 0;
+}
+
+int WidgetPluginParser::Impl::InsertLabel(const tizen_base::Database& db,
+ const std::string& classid,
+ const std::list<WidgetInfo::Label>& labels) {
+ for (const auto& i : labels) {
+ auto q = tizen_base::Database::Sql(
+ "INSERT OR REPLACE INTO label (classid, locale, label) "
+ "VALUES (?, ?, ?)")
+ .SetEmptyStringAsNull(true)
+ .Bind(classid)
+ .Bind(i.GetLang())
+ .Bind(i.GetLabel());
+ auto r = db.Exec(q);
+ if (!static_cast<bool>(r))
+ return -1;
+ }
+
+ return 0;
+}
+
+int WidgetPluginParser::Impl::InsertIcon(const tizen_base::Database& db,
+ const std::string& pkgid, const std::string& classid,
+ const std::list<WidgetInfo::Icon>& icons) {
+ for (const auto& i : icons) {
+ auto q = tizen_base::Database::Sql(
+ "INSERT OR REPLACE INTO icon (classid, locale, icon) "
+ "VALUES (?, ?, ?)")
+ .SetEmptyStringAsNull(true)
+ .Bind(classid)
+ .Bind(i.GetLang())
+ .Bind(ConvertPath(i.GetIcon(), pkgid));
+ auto r = db.Exec(q);
+ if (!static_cast<bool>(r))
+ return -1;
+ }
+
+ return 0;
+}
+
+} //namespace widget_service::parser
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+
+#ifndef WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_ERROR_H
+#define WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_ERROR_H
+
+#include <tizen_error.h>
+
+typedef enum widget_parser_error {
+ WIDGET_PARSER_ERROR_NONE = TIZEN_ERROR_NONE,
+ WIDGET_PARSER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,
+ WIDGET_PARSER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY,
+ WIDGET_PARSER_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY,
+ WIDGET_PARSER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED,
+ WIDGET_PARSER_ERROR_CANCELED = TIZEN_ERROR_CANCELED,
+ WIDGET_PARSER_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR,
+ WIDGET_PARSER_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT,
+ WIDGET_PARSER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED,
+ WIDGET_PARSER_ERROR_FILE_NO_SPACE_ON_DEVICE =
+ TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE,
+ WIDGET_PARSER_ERROR_FAULT = TIZEN_ERROR_WIDGET | 0x0001,
+ WIDGET_PARSER_ERROR_ALREADY_EXIST = TIZEN_ERROR_WIDGET | 0x0002,
+ WIDGET_PARSER_ERROR_ALREADY_STARTED = TIZEN_ERROR_WIDGET | 0x0004,
+ WIDGET_PARSER_ERROR_NOT_EXIST = TIZEN_ERROR_WIDGET | 0x0008,
+ WIDGET_PARSER_ERROR_DISABLED = TIZEN_ERROR_WIDGET | 0x0010,
+ WIDGET_PARSER_ERROR_MAX_EXCEEDED = TIZEN_ERROR_WIDGET | 0x0011,
+} widget_parser_error_e;
+
+#endif // WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_ERROR_H
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+
+#ifndef WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_IMPL_HH
+#define WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_IMPL_HH
+
+#include "widget_plugin_parser.hh"
+#include <database.hpp>
+
+namespace widget_service::parser {
+
+class WidgetPluginParser::Impl {
+ private:
+ friend class WidgetPluginParser;
+ int InsertWidgetClass(const tizen_base::Database& db,
+ const std::string& pkgid);
+ int RemoveWidgetClass(const tizen_base::Database& db,
+ const std::string& pkgid);
+ int InsertSupportSize(const tizen_base::Database& db,
+ const std::string& pkgid, const std::string& classid,
+ const std::list<WidgetInfo::SupportSize>& sizes);
+ int InsertLabel(const tizen_base::Database& db,
+ const std::string& classid,
+ const std::list<WidgetInfo::Label>& labels);
+ int InsertIcon(const tizen_base::Database& db,
+ const std::string& pkgid, const std::string& classid,
+ const std::list<WidgetInfo::Icon>& icons);
+
+ private:
+ std::list<WidgetInfo> info_list_;
+};
+
+} // namespace widget_service::parser
+
+#endif // WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_IMPL_HH
--- /dev/null
+/*
+ * Copyright (c) 2022 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.
+ */
+
+
+#ifndef WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_LOG_H
+#define WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_LOG_H
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#define LOG_TAG "WIDGET_PARSER_PLUGIN_PARSER"
+#endif
+
+#endif // WIDGET_SERVICE_PARSER_WIDGET_PLUGIN_PARSER_LOG_H
+++ /dev/null
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <libxml/tree.h>
-#include <glib.h>
-
-#include <dlog.h>
-
-#include "widget_plugin_parser_internal.h"
-
-enum widget_tag {
- TAG_WIDGET_APPLICATION = 1,
- TAG_COMPONENT_BASED_APPLICATION,
- TAG_WIDGET_COMPONENT,
- 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 },
- { "component-based-application", TAG_COMPONENT_BASED_APPLICATION },
- { "widget-component", TAG_WIDGET_COMPONENT },
- { "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);
- free(val);
- return -1;
- }
- size->width = atoi(tok);
- tok = strtok_r(NULL, "xX", &ptr);
- if (tok == NULL) {
- free(size);
- free(val);
- 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->appid);
- 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");
-
- val = _get_attribute(node, "max-instance");
- if (val)
- wc->max_instance = atoi(val);
- free(val);
-
- 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);
- free(val);
-
- val = _get_attribute(node, "nodisplay");
- if (val && strncmp(val, "true", strlen("true")) == 0)
- wc->nodisplay = 1;
- else
- wc->nodisplay = 0;
- free(val);
-
- wc->setup_appid = _get_attribute(node, "setup-appid");
-
- val = _get_attribute(node, "max-instance");
- if (val)
- wc->max_instance = atoi(val);
- free(val);
-
- val = _get_attribute(node, "main");
- if (val && strcmp(val, "true") == 0)
- wc->prime = 1;
- else
- wc->prime = 0;
- free(val);
-
- 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;
-}
-
-static int _parse_widget_component(xmlNode *node, const char *appid,
- GList **list)
-{
- 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, "id");
- if (val == NULL) {
- free(wc->appid);
- 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);
-
- val = _get_attribute(node, "icon-display");
- if (val && strncmp(val, "true", strlen("true")) == 0)
- wc->nodisplay = 1;
- else
- wc->nodisplay = 0;
- free(val);
-
- wc->setup_appid = _get_attribute(node, "setup-appid");
-
- val = _get_attribute(node, "max-instance");
- if (val)
- wc->max_instance = atoi(val);
- free(val);
-
- val = _get_attribute(node, "main");
- if (val && strcmp(val, "true") == 0)
- wc->prime = 1;
- else
- wc->prime = 0;
- free(val);
-
- 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:
- continue;
- }
- }
-
- *list = g_list_append(*list, wc);
-
- return 0;
-}
-
-int widget_plugin_parser_parse_manifest(xmlDocPtr doc, GList **list)
-{
- xmlNode *root;
- xmlNode *tmp;
- xmlNode *tmp_comp;
- char *appid;
-
- if (!tag_table) {
- LOGE("parser is not initialized");
- return WIDGET_PARSER_ERROR_INVALID_PARAMETER;
- }
-
- if (doc == NULL) {
- LOGE("invalid parameter");
- return WIDGET_PARSER_ERROR_INVALID_PARAMETER;
- }
-
- root = xmlDocGetRootElement(doc);
- if (root == NULL) {
- LOGE("failed to get root element");
- return WIDGET_PARSER_ERROR_INVALID_PARAMETER;
- }
-
- for (tmp = root->children; tmp; tmp = tmp->next) {
- switch (_get_tag(tmp)) {
- case TAG_WIDGET_APPLICATION:
- if (_parse_widget_application(tmp, list)) {
- LOGE("parse failed");
- return WIDGET_PARSER_ERROR_IO_ERROR;
- }
- break;
- case TAG_COMPONENT_BASED_APPLICATION:
- for (tmp_comp = tmp->children; tmp_comp; tmp_comp = tmp_comp->next) {
- if (_get_tag(tmp_comp) != TAG_WIDGET_COMPONENT)
- continue;
-
- appid = _get_attribute(tmp, "appid");
- if (appid == NULL)
- return WIDGET_PARSER_ERROR_IO_ERROR;
-
- if (_parse_widget_component(tmp_comp, appid, list)) {
- LOGE("parse failed");
- free(appid);
- return WIDGET_PARSER_ERROR_IO_ERROR;
- }
- free(appid);
- }
- break;
- default:
- continue;
- }
- }
-
- if (*list == NULL)
- return WIDGET_PARSER_ERROR_NOT_EXIST;
-
- return WIDGET_PARSER_ERROR_NONE;
-}
+++ /dev/null
-/*
- * 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 <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <linux/limits.h>
-
-#include <glib.h>
-#include <sqlite3.h>
-
-#include <dlog.h>
-#include <tzplatform_config.h>
-#include <pkgmgr-info.h>
-#include <pkgmgr_installer_info.h>
-
-#include "widget_plugin_parser_internal.h"
-
-static int target_uid_initialized;
-static uid_t target_uid;
-static int root_path_initialized;
-static char root_path[PATH_MAX];
-
-static uid_t __get_target_uid(void)
-{
- int ret;
-
- if (target_uid_initialized)
- return target_uid;
-
- ret = pkgmgr_installer_info_get_target_uid(&target_uid);
- if (ret < 0)
- LOGE("Failed to get target uid - %d", ret);
-
- target_uid_initialized = 1;
-
- return target_uid;
-}
-
-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 const char *_get_root_path(const char *pkgid)
-{
- pkgmgrinfo_pkginfo_h pkginfo;
- char *path = NULL;
- uid_t uid = __get_target_uid();
- int ret;
-
- if (root_path_initialized)
- return root_path;
-
- ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
- if (ret != PMINFO_R_OK) {
- LOGE("Failed to get pkginfo - %d(%s)", ret, pkgid);
- return NULL;
- }
-
- ret = pkgmgrinfo_pkginfo_get_root_path(pkginfo, &path);
- if (ret != PMINFO_R_OK) {
- LOGE("Failed to get root path - %d(%s)", ret, pkgid);
- pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
- return NULL;
- }
-
- snprintf(root_path, sizeof(root_path), "%s", path);
- pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
- root_path_initialized = 1;
-
- return root_path;
-}
-
-static int _insert_support_size(sqlite3 *db, const char *pkgid,
- const char *classid, GList *sizes)
-{
- int ret;
- static const char query[] =
- "INSERT OR REPLACE INTO support_size "
- "(classid, preview, frame, width, height) "
- "VALUES (?, ?, ?, ?, ?)";
- GList *tmp;
- struct support_size *size;
- sqlite3_stmt *stmt = NULL;
- int idx;
- char buf[PATH_MAX];
-
- 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);
- /* adjust preview image path */
- if (size->preview != NULL) {
- if (size->preview[0] == '/') {
- snprintf(buf, sizeof(buf), "%s", size->preview);
- } else {
- snprintf(buf, sizeof(buf), "%s/shared/res/%s",
- _get_root_path(pkgid),
- size->preview);
- }
- _bind_text(stmt, idx++, buf);
- } else {
- _bind_text(stmt, idx++, NULL);
- }
- 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 OR REPLACE 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 *pkgid,
- const char *classid, GList *icons)
-{
- int ret;
- static const char query[] =
- "INSERT OR REPLACE INTO icon (classid, locale, icon) "
- "VALUES (?, ?, ?)";
- GList *tmp;
- struct icon *icon;
- sqlite3_stmt *stmt = NULL;
- int idx;
- char buf[PATH_MAX];
-
- 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);
- /* adjust icon path */
- if (icon->icon[0] == '/') {
- snprintf(buf, sizeof(buf), "%s", icon->icon);
- } else {
- snprintf(buf, sizeof(buf), "%s/shared/res/%s",
- _get_root_path(pkgid), icon->icon);
- }
- _bind_text(stmt, idx++, buf);
-
- 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 OR REPLACE INTO widget_class (classid, update_period, "
- "setup_appid, appid, pkgid, nodisplay, max_instance, prime) "
- "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);
- sqlite3_bind_int(stmt, idx++, wc->nodisplay);
- sqlite3_bind_int(stmt, idx++, wc->max_instance);
- sqlite3_bind_int(stmt, idx++, wc->prime);
-
- ret = sqlite3_step(stmt);
- if (ret != SQLITE_DONE) {
- LOGE("step error: %s", sqlite3_errmsg(db));
- ret = -1;
- break;
- }
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- if (_insert_support_size(db, pkgid, wc->classid,
- wc->support_size)) {
- LOGE("Failed to insert support size");
- ret = -1;
- break;
- }
- if (_insert_label(db, wc->classid, wc->label)) {
- LOGE("Failed to insert label");
- ret = -1;
- break;
- }
- if (_insert_icon(db, pkgid, wc->classid, wc->icon)) {
- LOGE("Failed to insert icon");
- ret = -1;
- break;
- }
- ret = 0;
- }
-
- if (stmt)
- sqlite3_finalize(stmt);
-
- return ret;
-}
-
-int widget_parser_db_insert_widget_class(const char *pkgid, GList *widget_list)
-{
- int ret;
- sqlite3 *db;
-
- db = _open_db(__get_target_uid(), 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(__get_target_uid(), 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;
-}
+++ /dev/null
-/*
- * 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 <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <glib.h>
-#include <sqlite3.h>
-
-#include <dlog.h>
-#include <tzplatform_config.h>
-
-#include "widget_plugin_parser_internal.h"
-
-#define BUSY_WAITING_USEC 50000 /* 0.05 sec */
-#define BUSY_WAITING_MAX 20 /* wait for max 1 sec */
-
-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 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, ".widget.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;
-}
-
-sqlite3 *_open_db(uid_t uid, bool readonly)
-{
- int ret;
- sqlite3 *db;
- const 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);
- 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;
-}
-
-void _close_db(sqlite3 *db)
-{
- sqlite3_close_v2(db);
-}
+++ /dev/null
-#ifndef __WIDGET_PARSER_PLUGIN_PARSER_INTERNAL_H__
-#define __WIDGET_PARSER_PLUGIN_PARSER_INTERNAL_H__
-
-#include <stdbool.h>
-#include <sys/types.h>
-
-#include <libxml/tree.h>
-#include <sqlite3.h>
-#include <glib.h>
-
-#ifndef API
-#define API __attribute__ ((visibility("default")))
-#endif
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#define LOG_TAG "WIDGET_PARSER_PLUGIN_PARSER"
-#endif
-
-typedef enum widget_parser_error {
- WIDGET_PARSER_ERROR_NONE = TIZEN_ERROR_NONE,
- WIDGET_PARSER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,
- WIDGET_PARSER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY,
- WIDGET_PARSER_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY,
- WIDGET_PARSER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED,
- WIDGET_PARSER_ERROR_CANCELED = TIZEN_ERROR_CANCELED,
- WIDGET_PARSER_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR,
- WIDGET_PARSER_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT,
- WIDGET_PARSER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED,
- WIDGET_PARSER_ERROR_FILE_NO_SPACE_ON_DEVICE = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE,
- WIDGET_PARSER_ERROR_FAULT = TIZEN_ERROR_WIDGET | 0x0001,
- WIDGET_PARSER_ERROR_ALREADY_EXIST = TIZEN_ERROR_WIDGET | 0x0002,
- WIDGET_PARSER_ERROR_ALREADY_STARTED = TIZEN_ERROR_WIDGET | 0x0004,
- WIDGET_PARSER_ERROR_NOT_EXIST = TIZEN_ERROR_WIDGET | 0x0008,
- WIDGET_PARSER_ERROR_DISABLED = TIZEN_ERROR_WIDGET | 0x0010,
- WIDGET_PARSER_ERROR_MAX_EXCEEDED = TIZEN_ERROR_WIDGET | 0x0011,
-} widget_parser_error_e;
-
-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;
- int max_instance;
- int nodisplay;
- int prime;
- GList *support_size;
- GList *label;
- GList *icon;
-};
-
-int widget_plugin_parser_init(void);
-int widget_plugin_parser_fini(void);
-int widget_plugin_parser_parse_manifest(xmlDocPtr doc, GList **widget_list);
-
-
-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
+++ /dev/null
-/*
- * 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 <glib.h>
-#include <libxml/tree.h>
-
-#include <dlog.h>
-
-#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 = NULL;
-
- int ret = widget_plugin_parser_parse_manifest(doc, &result);
- if (ret == WIDGET_PARSER_ERROR_NOT_EXIST) {
- LOGW("not exist");
- return 0;
- }
-
- if (ret != WIDGET_PARSER_ERROR_NONE) {
- LOGE("parse failed");
- return -1;
- }
-
- if (widget_parser_db_insert_widget_class(pkgid, result)) {
- g_list_free_full(result, _free_widget_class);
- 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 = NULL;
-
- int ret = widget_plugin_parser_parse_manifest(doc, &result);
- if (ret == WIDGET_PARSER_ERROR_NOT_EXIST) {
- LOGW("not exist");
- return 0;
- }
-
- if (ret != WIDGET_PARSER_ERROR_NONE) {
- LOGE("parse failed");
- return -1;
- }
-
- if (widget_parser_db_remove_widget_class(pkgid)) {
- g_list_free_full(result, _free_widget_class);
- return -1;
- }
-
- if (widget_parser_db_insert_widget_class(pkgid, result)) {
- g_list_free_full(result, _free_widget_class);
- 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();
-}
--- /dev/null
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"WIDGET_SERVICE\"")
+ADD_DEFINITIONS("-DNDEBUG")
+ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET")
+ADD_DEFINITIONS("-DRESOLUTION_FILE=\"/usr/share/widget-service/resolution.ini\"")
+
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} LIB_SRCS)
+
+ADD_LIBRARY(${TARGET_WIDGET_SERVICE} SHARED ${LIB_SRCS})
+
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_SERVICE} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_SERVICE} PROPERTIES VERSION ${FULLVER})
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_SERVICE} PROPERTIES OUTPUT_NAME widget_service)
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_SERVICE} PROPERTIES COMPILE_FLAGS
+ ${CFLAGS} "-fpic")
+SET_TARGET_PROPERTIES(${TARGET_WIDGET_SERVICE} PROPERTIES LINK_FLAGS "-ldl -lpthread")
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_WIDGET_SERVICE} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include)
+
+APPLY_PKG_CONFIG(${TARGET_WIDGET_SERVICE} PUBLIC
+ DLOG_DEPS
+ GLIB_DEPS
+ GIO_DEPS
+ SQLITE3_DEPS
+ DB_UTIL_DEPS
+ PKGMGR_INFO_DEPS
+ VCONF_DEPS
+ ICU_UC_DEPS
+ BUNDLE_DEPS
+ CAPI_BASE_COMMON_DEPS
+ CAPI_SYSTEM_INFO_DEPS
+ CAPI_APPFW_APP_COMMON_DEPS
+ AUL_DEPS
+ PLATFORM_CONFIG_DEPS
+ UUID_DEPS
+ CYNARA_CLIENT_DEPS
+ INIPARSER_DEPS
+ SMACK_DEPS
+)
+
+INSTALL(TARGETS ${TARGET_WIDGET_SERVICE} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_WIDGET_SERVICE}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+CONFIGURE_FILE(${TARGET_WIDGET_SERVICE}.pc.in ${TARGET_WIDGET_SERVICE}.pc @ONLY)
+SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${TARGET_WIDGET_SERVICE}.pc")
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/widget_service.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/widget_service_internal.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/widget_errno.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/widget_instance.h DESTINATION include/${PROJECT_NAME})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.resolution.ini DESTINATION /usr/share/${PROJECT_NAME} RENAME "mobile.resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.resolution.ini DESTINATION /usr/share/${PROJECT_NAME} RENAME "wearable.resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.320x480.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/320x480 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.480x800.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/480x800 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.360x480.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/360x480 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.360x360.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/360x360 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/720x1280 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.wearable.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/320x320 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.540x960.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/540x960 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.600x1024.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/600x1024 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.1080x1920.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1080x1920 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.1440x2560.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1440x2560 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.mobile.1440x3040.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1440x3040 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/data/wayland.common.1280x720.resolution.ini DESTINATION /usr/share/${PROJECT_NAME}/1280x720 RENAME "resolution.ini" PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
glib-2.0
sqlite3
bundle
+ libxml-2.0
)
FOREACH(flag ${widget_service_unittests_CFLAGS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/mock)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../parser/lib)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock MOCK_SOURCES)
AUX_SOURCE_DIRECTORY(src SOURCES)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../src WIDGET_SERVICE_SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../parser/lib WIDGET_PARSER_SOURCES)
ADD_EXECUTABLE(${PROJECT_NAME}
${SOURCES}
${MOCK_SOURCES}
${WIDGET_SERVICE_SOURCES}
+ ${WIDGET_PARSER_SOURCES}
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${widget_service_unittests_LDFLAGS}
${pkgs_LIBRARIES}
gmock
widget_service
+ widget_parser
"-ldl"
)
extern "C" int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_appinfo_h arg1) {
return MOCK_HOOK_P1(PkgMgrInfoMock, pkgmgrinfo_pkginfo_destroy_pkginfo, arg1);
-}
\ No newline at end of file
+}
+
+extern "C" int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle,
+ char** root_path) {
+ return MOCK_HOOK_P2(PkgMgrInfoMock, pkgmgrinfo_pkginfo_get_root_path, handle,
+ root_path);
+}
int (pkgmgrinfo_pkginfo_h, char**));
MOCK_METHOD1(pkgmgrinfo_pkginfo_destroy_pkginfo,
int (pkgmgrinfo_pkginfo_h));
+ MOCK_METHOD2(pkgmgrinfo_pkginfo_get_root_path,
+ int (pkgmgrinfo_pkginfo_h, char**));
};
#endif // UNIT_TESTS_MOCK_PKGMGR_INFO_MOCK_H_
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2020 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 "mock_hook.h"
-#include "test_fixture.h"
-#include "sqlite3_mock.h"
-
-typedef int(*cb)(void*, int);
-typedef int(*execcb)(void*, int, char**, char**);
-typedef void(*bindcb)(void*);
-
-extern "C" int sqlite3_step(sqlite3_stmt* arg0) {
- return MOCK_HOOK_P1(SqlMock, sqlite3_step, arg0);
-}
-
-extern "C" int sqlite3_prepare_v2(sqlite3* arg0, const char* arg1,
- int arg2, sqlite3_stmt** arg3, const char** arg4) {
- return MOCK_HOOK_P5(SqlMock, sqlite3_prepare_v2, arg0, arg1, arg2, arg3, arg4);
-}
-
-extern "C" int sqlite3_open_v2(const char* arg0,
- sqlite3** arg1, int arg2, const char* arg3) {
- return MOCK_HOOK_P4(SqlMock, sqlite3_open_v2, arg0, arg1, arg2, arg3);
-}
-
-extern "C" int sqlite3_close_v2(sqlite3* arg0) {
- return MOCK_HOOK_P1(SqlMock, sqlite3_close_v2, arg0);
-}
-
-extern "C" int sqlite3_changes(sqlite3* arg0) {
- return MOCK_HOOK_P1(SqlMock, sqlite3_changes, arg0);
-}
-
-extern "C" void sqlite3_free_table(char** arg0) {
- return MOCK_HOOK_P1(SqlMock, sqlite3_free_table, arg0);
-}
-
-extern "C" int sqlite3_busy_handler(sqlite3* arg0, cb arg1, void* arg2) {
- return MOCK_HOOK_P3(SqlMock, sqlite3_busy_handler, arg0, arg1, arg2);
-}
-
-extern "C" int sqlite3_get_table(sqlite3* arg0, const char* arg1,
- char*** arg2, int* arg3, int* arg4, char** arg5) {
- return MOCK_HOOK_P6(SqlMock, sqlite3_get_table, arg0, arg1, arg2, arg3,
- arg4, arg5);
-}
-
-extern "C" int sqlite3_exec(sqlite3* arg0, const char* arg1,
- execcb arg2, void* arg3, char** arg4) {
- return MOCK_HOOK_P5(SqlMock, sqlite3_exec, arg0, arg1, arg2, arg3, arg4);
-}
-
-extern "C" int sqlite3_prepare(sqlite3* arg0, const char* arg1,
- int arg2, sqlite3_stmt** arg3, const char** arg4) {
- return MOCK_HOOK_P5(SqlMock, sqlite3_prepare, arg0, arg1, arg2, arg3, arg4);
-}
-
-extern "C" int sqlite3_bind_text(sqlite3_stmt* arg0, int arg1, const char* arg2,
- int arg3, bindcb arg4) {
- return MOCK_HOOK_P5(SqlMock, sqlite3_bind_text, arg0, arg1, arg2, arg3, arg4);
-}
-
-extern "C" int sqlite3_bind_int(sqlite3_stmt* arg0, int arg1, int arg2) {
- return MOCK_HOOK_P3(SqlMock, sqlite3_bind_int, arg0, arg1, arg2);
-}
-
-extern "C" int sqlite3_bind_double(sqlite3_stmt* arg0, int arg1, double arg2) {
- return MOCK_HOOK_P3(SqlMock, sqlite3_bind_double, arg0, arg1, arg2);
-}
-
-extern "C" const unsigned char* sqlite3_column_text(sqlite3_stmt* arg0, int arg1) {
- return MOCK_HOOK_P2(SqlMock, sqlite3_column_text, arg0, arg1);
-}
-
-extern "C" int sqlite3_column_int(sqlite3_stmt* arg0, int arg1) {
- return MOCK_HOOK_P2(SqlMock, sqlite3_column_int, arg0, arg1);
-}
-
-extern "C" double sqlite3_column_double(sqlite3_stmt* arg0, int arg1) {
- return MOCK_HOOK_P2(SqlMock, sqlite3_column_double, arg0, arg1);
-}
-
-extern "C" int sqlite3_finalize(sqlite3_stmt* arg0) {
- return MOCK_HOOK_P1(SqlMock, sqlite3_finalize, arg0);
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2020 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.
- */
-
-#ifndef UNIT_TESTS_MOCK_SQLITE3_MOCK_H_
-#define UNIT_TESTS_MOCK_SQLITE3_MOCK_H_
-
-#include <gmock/gmock.h>
-#include <sqlite3.h>
-
-#include "module_mock.h"
-
-class SqlMock : public virtual ModuleMock {
- public:
- virtual ~SqlMock() {}
- MOCK_METHOD1(sqlite3_step, int(sqlite3_stmt*));
- MOCK_METHOD5(sqlite3_prepare_v2, int(sqlite3*, const char*,
- int, sqlite3_stmt**, const char**));
-
- MOCK_METHOD1(sqlite3_free_table, void(char**));
- MOCK_METHOD1(sqlite3_close_v2, int(sqlite3*));
- MOCK_METHOD1(sqlite3_changes, int(sqlite3*));
- MOCK_METHOD3(sqlite3_busy_handler, int(sqlite3*, int(*)(void*, int), void*));
- MOCK_METHOD4(sqlite3_open_v2, int(const char*, sqlite3**, int, const char*));
- MOCK_METHOD6(sqlite3_get_table, int (sqlite3*, const char*, char***,
- int*, int*, char**));
- MOCK_METHOD5(sqlite3_exec, int(sqlite3*, const char*,
- int(*)(void*, int, char**, char**), void*, char**));
- MOCK_METHOD5(sqlite3_prepare, int(sqlite3*, const char*,
- int, sqlite3_stmt**, const char**));
-
- MOCK_METHOD5(sqlite3_bind_text, int(sqlite3_stmt*, int, const char*,
- int, void(*)(void*)));
- MOCK_METHOD3(sqlite3_bind_int, int(sqlite3_stmt*, int, int));
- MOCK_METHOD3(sqlite3_bind_double, int(sqlite3_stmt*, int, double));
- MOCK_METHOD2(sqlite3_column_text, const unsigned char*(sqlite3_stmt*, int));
- MOCK_METHOD2(sqlite3_column_int, int(sqlite3_stmt*, int));
- MOCK_METHOD2(sqlite3_column_double, double(sqlite3_stmt*, int));
- MOCK_METHOD1(sqlite3_finalize, int(sqlite3_stmt*));
-
-};
-
-#endif // UNIT_TESTS_MOCK_SQLITE3_MOCK_H_
#include <gtest/gtest.h>
#include <gmock/gmock.h>
+//#define LOG_INTERNAL
+
+#ifdef LOG_INTERNAL
+#include <dlog.h>
+
+extern "C" int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...) {
+ printf("%s:", tag);
+ va_list ap;
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ printf("\n");
+
+ return 0;
+}
+#endif
+
int main(int argc, char** argv){
int ret = -1;
try {
--- /dev/null
+/*
+ * Copyright (c) 2022 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 <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include <fstream>
+#include <vector>
+
+#include "pkgmgr-info_mock.h"
+#include "tzplatform_config_mock.h"
+#include "test_fixture.h"
+#include "widget_errno.h"
+#include "widget_plugin_parser.hh"
+#include "widget_plugin_parser_error.h"
+#include "widget_service_internal.h"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Invoke;
+using ::testing::SetArgPointee;
+using ::testing::Return;
+
+namespace {
+constexpr char XML1[] = R"__widget(<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5.5" package="org.tizen.gallery_common" version="1.0.0">
+ <profile name="tizeniot"/>
+ <profile name="mobile"/>
+ <ui-application appid="org.tizen.gallery" exec="gallery" hw-acceleration="on" multiple="false" nodisplay="false" process-pool="true" taskmanage="true" type="capp">
+ <label>Gallery</label>
+ <label xml:lang="en-us">Gallery</label>
+ <icon>org.tizen.gallery.png</icon>
+ </ui-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/mediastorage</privilege>
+ <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ <privilege>http://tizen.org/privilege/externalstorage</privilege>
+ <privilege>http://tizen.org/privilege/content.write</privilege>
+ <privilege>http://tizen.org/privilege/appdir.shareddata</privilege>
+ </privileges>
+ <widget-application appid="org.tizen.gallery.widget" exec="gallery-widget" hw-acceleration="on" main="true" update-period="0">
+ <label>Gallery</label>
+ <label xml:lang="fr-fr">Galerie</label>
+ <icon>preview_gallery_4x4.png</icon>
+ <support-size preview="preview_gallery_4x4.png">4x4</support-size>
+ </widget-application>
+</manifest>
+)__widget";
+
+constexpr char XML2[] = R"__widget(<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5" package="org.tizen.cssettings" version="1.0.0">
+ <profile name="common" />
+ <widget-application appid="org.tizen.cssettings"
+ exec="SettingMain.dll"
+ type="dotnet"
+ multiple="false"
+ taskmanage="true"
+ nodisplay="false"
+ launch_mode="single">
+ <label>SettingMain</label>
+ <icon>SettingMain.png</icon>
+ <widget-class classid="sound" update-period="0">
+ <support-size preview="SettingMain.png">4x4</support-size>
+ </widget-class>
+ <widget-class classid="soundmode" update-period="0">
+ <support-size preview="SettingMain.png">4x4</support-size>
+ </widget-class>
+ <widget-class classid="notificationsound" update-period="0">
+ <support-size preview="SettingMain.png">4x4</support-size>
+ </widget-class>
+ <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+ </widget-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/systemsettings.admin</privilege>
+ <privilege>http://tizen.org/privilege/telephony.admin</privilege>
+ <privilege>http://tizen.org/privilege/telephony</privilege>
+ </privileges>
+</manifest>
+)__widget";
+
+constexpr char XML3[] = R"__widget(<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5.5" package="org.tizen.comptest" version="0.1.1">
+ <label>TEAM</label>
+ <author email="tizen@samsung.com" href="www.samsung.com">Tizen</author>
+ <description>TEAM</description>
+ <component-based-application appid="org.tizen.comptest" exec="comptest" nodisplay="false" multiple="false" type="capp">
+ <label>TEAM</label>
+ <icon>comptest.png</icon>
+ <frame-component id="ElmFrame" launch_mode="caller" main="true" icon-display="false" taskmanage="true">
+ <icon>org.tizen.team.png</icon>
+ <label>ElmFrame</label>
+ <label xml:lang="en-us">EElmFrame</label>
+ <label xml:lang="ko-kr">KElmFrame</label>
+ </frame-component>
+ <frame-component id="CionServerFrame" launch_mode="caller" main="true" icon-display="true" taskmanage="true">
+ <icon>org.tizen.team.png</icon>
+ <label>ServerFrame</label>
+ <label xml:lang="en-us">EServerFrame</label>
+ <label xml:lang="ko-kr">KServerFrame</label>
+ </frame-component>
+ <frame-component id="CionClientFrame" launch_mode="caller" main="true" icon-display="true" taskmanage="true">
+ <icon>org.tizen.team.png</icon>
+ <label>ClientFrame</label>
+ <label xml:lang="en-us">EClientFrame</label>
+ <label xml:lang="ko-kr">KClientFrame</label>
+ </frame-component>
+ <frame-component id="CionBroadcastFrame" launch_mode="caller" main="true" icon-display="true" taskmanage="true">
+ <icon>org.tizen.team.png</icon>
+ <label>BroadcastFrame</label>
+ <label xml:lang="en-us">EBroadcastFrame</label>
+ <label xml:lang="ko-kr">KBroadcastFrame</label>
+ </frame-component>
+ <frame-component id="EflFrame" launch_mode="caller">
+ <icon>org.tizen.team.png</icon>
+ <label>EflFrame</label>
+ <label xml:lang="en-us">EngEflFrame</label>
+ </frame-component>
+ <frame-component id="Frame" launch_mode="caller">
+ <label>Frame</label>
+ <label xml:lang="en-us">EngFrame</label>
+ </frame-component>
+ <widget-component id="Widget" main="true" update-period="0" max-instance="1" setup-appid="org.tizen.widget-setting">
+ <label>Widget</label>
+ <label xml:lang="en-us">EngWidget</label>
+ <icon>org.tizen.team.png</icon>
+ <label>component-widget</label>
+ <label xml:lang="en-us">component-widget</label>
+ <label xml:lang="ko-kr">component-widget[KOR]</label>
+ <support-size preview="org.tizen.team.png">2x2</support-size>
+ <support-size preview="org.tizen.team.png">4x4</support-size>
+ </widget-component>
+ <service-component id="Service" main="true">
+ <label>Service</label>
+ <label xml:lang="en-us">EngService</label>
+ </service-component>
+ </component-based-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ <privilege>http://tizen.org/privilege/datasharing</privilege>
+ <privilege>http://tizen.org/privilege/network.get</privilege>
+ <privilege>http://tizen.org/privilege/network.set</privilege>
+ <privilege>http://tizen.org/privilege/internet</privilege>
+ </privileges>
+</manifest>
+)__widget";
+
+class Mocks : virtual public ::testing::NiceMock<PkgMgrInfoMock>,
+ virtual public ::testing::NiceMock<TzplatformConfigMock> {};
+
+const char *__fake_tzplatform_mkpath(enum tzplatform_variable id, const char *path) {
+ return ".widget_test.db";
+}
+
+} // namespace
+
+class WidgetPluginParserTest : public TestFixture {
+ public:
+ WidgetPluginParserTest() : TestFixture(std::make_unique<::Mocks>()) {}
+
+ void SetUp() override {
+ EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
+ .WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
+ int ret = widget_service_check_db_integrity(false);
+ ASSERT_EQ(ret, WIDGET_ERROR_NONE);
+ }
+
+ void TearDown() override {
+ remove(".widget_test.db");
+ }
+
+ void MakeDb() {
+ int ret = widget_service_check_db_integrity(false);
+ ASSERT_EQ(ret, WIDGET_ERROR_NONE);
+ }
+};
+
+TEST_F(WidgetPluginParserTest, ParseManifest_N) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ int ret = parser.ParseManifest(nullptr);
+ EXPECT_EQ(ret, WIDGET_PARSER_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(WidgetPluginParserTest, ParseManifest1) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ auto* doc = xmlParseDoc((xmlChar*)XML1);
+ int ret = parser.ParseManifest(doc);
+ EXPECT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ auto& info = parser.GetWidgetInfoList();
+ EXPECT_EQ(info.size(), 1);
+ EXPECT_EQ(info.front().GetAppId(), "org.tizen.gallery.widget");
+ EXPECT_EQ(info.front().GetClassId(), "org.tizen.gallery.widget");
+ EXPECT_EQ(info.front().GetSetupAppId(), "");
+ EXPECT_EQ(info.front().GetUpdatePeriod(), 0);
+ EXPECT_EQ(info.front().GetMaxInstance(), 0);
+ EXPECT_EQ(info.front().GetNoDisplay(), 0);
+ EXPECT_EQ(info.front().GetPrime(), 1);
+ auto& sizes = info.front().GetSupportSizeList();
+ EXPECT_EQ(sizes.size(), 1);
+ EXPECT_EQ(sizes.front().GetWidth(), 4);
+ EXPECT_EQ(sizes.front().GetHeight(), 4);
+ EXPECT_EQ(sizes.front().GetPreview(), "preview_gallery_4x4.png");
+ EXPECT_FALSE(sizes.front().IsFrame());
+
+ auto& labels = info.front().GetLabelList();
+ EXPECT_EQ(labels.size(), 2);
+ std::vector<std::pair<std::string, std::string>> exp = {
+ { "Gallery", "" },
+ { "Galerie", "fr-fr"}
+ };
+
+ int idx = 0;
+ for (const auto& i : labels) {
+ EXPECT_EQ(i.GetLabel(), exp[idx].first);
+ EXPECT_EQ(i.GetLang(), exp[idx].second);
+ idx++;
+ }
+
+ auto& icons = info.front().GetIconList();
+ EXPECT_EQ(icons.size(), 1);
+ EXPECT_EQ(icons.front().GetIcon(), "preview_gallery_4x4.png");
+ EXPECT_EQ(icons.front().GetLang(), "");
+}
+
+TEST_F(WidgetPluginParserTest, ParseManifest2) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ auto* doc = xmlParseDoc((xmlChar*)XML2);
+ int ret = parser.ParseManifest(doc);
+ EXPECT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ auto& info = parser.GetWidgetInfoList();
+ EXPECT_EQ(info.size(), 4);
+
+ std::vector<std::string> exp_class_id = {
+ "sound@org.tizen.cssettings",
+ "soundmode@org.tizen.cssettings",
+ "notificationsound@org.tizen.cssettings",
+ "org.tizen.cssettings"
+ };
+
+ int idx = 0;
+ for (const auto& i : info) {
+ EXPECT_EQ(i.GetClassId(), exp_class_id[idx]);
+ EXPECT_EQ(i.GetAppId(), "org.tizen.cssettings");
+ EXPECT_EQ(i.GetSetupAppId(), "");
+ EXPECT_EQ(i.GetNoDisplay(), 0);
+ EXPECT_EQ(i.GetMaxInstance(), 0);
+ EXPECT_EQ(i.GetPrime(), 0);
+ EXPECT_EQ(i.GetUpdatePeriod(), 0);
+ idx++;
+ }
+}
+
+TEST_F(WidgetPluginParserTest, ParseManifest3) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ auto* doc = xmlParseDoc((xmlChar*)XML3);
+ int ret = parser.ParseManifest(doc);
+ EXPECT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ auto& info = parser.GetWidgetInfoList();
+ EXPECT_EQ(info.size(), 1);
+
+ EXPECT_EQ(info.front().GetClassId(), "Widget@org.tizen.comptest");
+ EXPECT_EQ(info.front().GetAppId(), "org.tizen.comptest");
+ EXPECT_EQ(info.front().GetSetupAppId(), "org.tizen.widget-setting");
+ EXPECT_EQ(info.front().GetNoDisplay(), 0);
+ EXPECT_EQ(info.front().GetMaxInstance(), 1);
+ EXPECT_EQ(info.front().GetPrime(), 1);
+ EXPECT_EQ(info.front().GetUpdatePeriod(), 0);
+}
+
+TEST_F(WidgetPluginParserTest, InsertRemove1) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ auto* doc = xmlParseDoc((xmlChar*)XML1);
+ int ret = parser.ParseManifest(doc);
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ ret = parser.Insert("org.tizen.gallery_common");
+ EXPECT_EQ(ret, 0);
+ ret = parser.Remove("org.tizen.gallery_common");
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(WidgetPluginParserTest, InsertRemove2) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ auto* doc = xmlParseDoc((xmlChar*)XML2);
+ int ret = parser.ParseManifest(doc);
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ ret = parser.Insert("org.tizen.cssettings");
+ EXPECT_EQ(ret, 0);
+ ret = parser.Remove("org.tizen.cssettings");
+ EXPECT_EQ(ret, 0);
+}
+
+TEST_F(WidgetPluginParserTest, InsertRemove3) {
+ widget_service::parser::WidgetPluginParser parser;
+
+ auto* doc = xmlParseDoc((xmlChar*)XML3);
+ int ret = parser.ParseManifest(doc);
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ ret = parser.Insert("org.tizen.comptest");
+ EXPECT_EQ(ret, 0);
+ ret = parser.Remove("org.tizen.comptest");
+ EXPECT_EQ(ret, 0);
+}
#include "aul_mock.h"
#include "cynara_mock.h"
#include "glib_mock.h"
-#include "sqlite3_mock.h"
#include "tzplatform_config_mock.h"
#include "pkgmgr-info_mock.h"
#include "test_fixture.h"
+#include "widget_plugin_parser.hh"
+#include "widget_plugin_parser_error.h"
using ::testing::_;
using ::testing::DoAll;
virtual public ::testing::NiceMock<GlibMock>,
virtual public ::testing::NiceMock<PkgMgrInfoMock>,
virtual public ::testing::NiceMock<SystemInfoMock>,
- virtual public ::testing::NiceMock<SqlMock>,
virtual public ::testing::NiceMock<TzplatformConfigMock> {};
+constexpr char XML1[] = R"__widget(<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5.5" package="org.tizen.gallery_common" version="1.0.0">
+ <profile name="tizeniot"/>
+ <profile name="mobile"/>
+ <ui-application appid="org.tizen.gallery" exec="gallery" hw-acceleration="on" multiple="false" nodisplay="false" process-pool="true" taskmanage="true" type="capp">
+ <label>Gallery</label>
+ <label xml:lang="en-us">Gallery</label>
+ <icon>org.tizen.gallery.png</icon>
+ </ui-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/mediastorage</privilege>
+ <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ <privilege>http://tizen.org/privilege/externalstorage</privilege>
+ <privilege>http://tizen.org/privilege/content.write</privilege>
+ <privilege>http://tizen.org/privilege/appdir.shareddata</privilege>
+ </privileges>
+ <widget-application appid="org.tizen.gallery.widget" exec="gallery-widget"
+ hw-acceleration="on" main="true" update-period="0"
+ setup-appid="org.tizen.setup_appid" max-instance="3">
+ <label>Gallery</label>
+ <label xml:lang="en-us">Gallery</label>
+ <label xml:lang="fr-fr">Galerie</label>
+ <icon>preview_gallery_4x4.png</icon>
+ <support-size preview="preview_gallery_4x4.png">4x4</support-size>
+ </widget-application>
+</manifest>
+)__widget";
+
} // namespace
class WidgetServiceTest : public TestFixture {
public:
WidgetServiceTest() : TestFixture(std::make_unique<::Mocks>()) {}
void SetUp() override {
- table_ = (char** )calloc(10, sizeof(char*));
- db_ = (sqlite3*) table_;
+ EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
+ .WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
+
+ int ret = widget_service_check_db_integrity(false);
+ ASSERT_EQ(ret, WIDGET_ERROR_NONE);
+
+ widget_service::parser::WidgetPluginParser parser;
+ auto* doc = xmlParseDoc((xmlChar*)XML1);
+ ret = parser.ParseManifest(doc);
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ ret = parser.Insert("org.tizen.gallery_common");
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
}
+
void TearDown() override {
- free(table_);
+ remove(".widget_test.db");
}
-
- char **table_;
- sqlite3 *db_;
};
/* internal api */
int ret;
- ret = widget_service_set_widget_disabled("org.tizen.test_widget", true);
+ ret = widget_service_set_widget_disabled("org.tizen.gallery.widget", true);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillOnce(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillOnce(Return(SQLITE_ROW));
int ret = WIDGET_ERROR_NONE;
bool is_disabled;
- ret = widget_service_get_widget_disabled("org.tizen.test_widget",
+ ret = widget_service_get_widget_disabled("org.tizen.gallery.widget",
&is_disabled);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
int ret;
bool need_of_event;
- ret = widget_service_get_need_of_mouse_event("org.tizen.test_widget", WIDGET_SIZE_TYPE_4x2,
- &need_of_event);
+ ret = widget_service_get_need_of_mouse_event("org.tizen.gallery.widget",
+ WIDGET_SIZE_TYPE_4x2, &need_of_event);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
int ret;
bool need_of_event;
- ret = widget_service_get_need_of_touch_effect("org.tizen.test_widget", WIDGET_SIZE_TYPE_4x2,
- &need_of_event);
+ ret = widget_service_get_need_of_touch_effect("org.tizen.gallery.widget",
+ WIDGET_SIZE_TYPE_4x2, &need_of_event);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
int ret;
bool need_of_frame;
- ret = widget_service_get_need_of_frame("org.tizen.test_widget", WIDGET_SIZE_TYPE_4x2,
- &need_of_frame);
+ ret = widget_service_get_need_of_frame("org.tizen.gallery.widget",
+ WIDGET_SIZE_TYPE_4x2, &need_of_frame);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
int ret;
- ret = widget_service_trigger_update("org.tizen.test_widget",
- "org.tizen.test_widget", NULL, 1);
+ ret = widget_service_trigger_update("org.tizen.gallery.widget",
+ "org.tizen.gallery.widget", NULL, 1);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
int ret;
- ret = widget_service_change_period("org.tizen.test_widget",
- "org.tizen.test_widget", 1.0);
+ ret = widget_service_change_period("org.tizen.gallery.widget",
+ "org.tizen.gallery.widget", 1.0);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
.WillRepeatedly(Invoke(__fake_cynara_check));
EXPECT_CALL(GetMock<CynaraMock>(), cynara_finish(_))
.WillRepeatedly(Invoke(__fake_cynara_finish));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
EXPECT_CALL(GetMock<GlibMock>(),
g_list_length(_)).WillOnce(Return(1));
.WillRepeatedly(Invoke(__fake_pkgmgrinfo_pkginfo_destroy_pkginfo));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_int(_, _))
- .WillRepeatedly(Return(3));
char *app_id = NULL;
- app_id = widget_service_get_main_app_id("org.tizen.test_widget");
+ app_id = widget_service_get_main_app_id("org.tizen.gallery.widget");
auto p = std::unique_ptr<char, decltype(std::free)*>(app_id, std::free);
ASSERT_STREQ(p.get(), "org.tizen.mainappid");
}
int ret;
- ret = widget_service_get_widget_list_by_pkgid("org.tizen.test_widget", _widget_list_by_pkgid_cb, NULL);
+ ret = widget_service_get_widget_list_by_pkgid("org.tizen.gallery.widget",
+ _widget_list_by_pkgid_cb, NULL);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
.WillRepeatedly(Invoke(__fake_pkgmgrinfo_pkginfo_get_mainappid));
EXPECT_CALL(GetMock<PkgMgrInfoMock>(), pkgmgrinfo_pkginfo_destroy_pkginfo(_))
.WillRepeatedly(Invoke(__fake_pkgmgrinfo_pkginfo_destroy_pkginfo));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_text(_, _))
- .WillRepeatedly(Return((unsigned char*)"org.tizen.test_widget"));
char *widget_id = NULL;
- widget_id = widget_service_get_widget_id("org.tizen.test_appid");
+ widget_id = widget_service_get_widget_id("org.tizen.gallery.widget");
auto p = std::unique_ptr<char, decltype(std::free)*>(widget_id, std::free);
- ASSERT_STREQ(p.get(), "org.tizen.test_widget");
+ ASSERT_STREQ(p.get(), "org.tizen.gallery.widget");
}
TEST_F(WidgetServiceTest, GetAppIdOfSetupApp) {
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_text(_, _))
- .WillRepeatedly(Return((unsigned char*)"org.tizen.setup_appid"));
char *app_id = NULL;
- app_id = widget_service_get_app_id_of_setup_app("org.tizen.test_widget");
+ app_id = widget_service_get_app_id_of_setup_app("org.tizen.gallery.widget");
auto p = std::unique_ptr<char, decltype(std::free)*>(app_id, std::free);
ASSERT_STREQ(p.get(), "org.tizen.setup_appid");
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_text(_, _))
- .WillRepeatedly(Return((unsigned char*)"org.tizen.test_pkgid"));
char *package_id = NULL;
- package_id = widget_service_get_package_id("org.tizen.test_widget");
+ package_id = widget_service_get_package_id("org.tizen.gallery.widget");
auto p = std::unique_ptr<char, decltype(std::free)*>(package_id, std::free);
- ASSERT_STREQ(p.get(), "org.tizen.test_pkgid");
+ ASSERT_STREQ(p.get(), "org.tizen.gallery_common");
}
TEST_F(WidgetServiceTest, GetName) {
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_text(_, _))
- .WillRepeatedly(Return((unsigned char*)"TestWidget"));
char *name = NULL;
- name = widget_service_get_name("org.tizen.test_widget", "en-us");
+ name = widget_service_get_name("org.tizen.gallery.widget", "en-us");
auto p = std::unique_ptr<char, decltype(std::free)*>(name, std::free);
- ASSERT_STREQ(p.get(), "TestWidget");
+ ASSERT_STREQ(p.get(), "Gallery");
}
TEST_F(WidgetServiceTest, GetPreviewImagePath) {
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_text(_, _))
- .WillRepeatedly(Return((unsigned char*)"/unittest/preview.png"));
char *path = NULL;
path = widget_service_get_preview_image_path(
- "org.tizen.test_widget", WIDGET_SIZE_TYPE_4x2);
+ "org.tizen.gallery.widget", WIDGET_SIZE_TYPE_4x4);
auto p = std::unique_ptr<char, decltype(std::free)*>(path, std::free);
- ASSERT_STREQ(p.get(), "/unittest/preview.png");
+ ASSERT_STREQ(p.get(), ".//shared/res/preview_gallery_4x4.png");
}
TEST_F(WidgetServiceTest, GetIcon) {
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_text(_, _))
- .WillRepeatedly(Return((unsigned char*)"/unittest/icon.png"));
char *path = NULL;
- path = widget_service_get_icon("org.tizen.test_pkgid", "en-us");
+ path = widget_service_get_icon("org.tizen.gallery_common", "");
auto p = std::unique_ptr<char, decltype(std::free)*>(path, std::free);
- ASSERT_STREQ(p.get(), "/unittest/icon.png");
+ ASSERT_STREQ(p.get(), ".//shared/res/preview_gallery_4x4.png");
}
TEST_F(WidgetServiceTest, GetNodisplay) {
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_int(_, _))
- .WillRepeatedly(Return(2));
int ret = WIDGET_ERROR_NONE;
- ret = widget_service_get_nodisplay("org.tizen.test_widget");
- ASSERT_EQ(ret, 2);
+ ret = widget_service_get_nodisplay("org.tizen.gallery.widget");
+ ASSERT_EQ(ret, 0);
}
TEST_F(WidgetServiceTest, GetSupportedSizes) {
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).Times(3)
- .WillOnce(Return(SQLITE_ROW))
- .WillOnce(Return(SQLITE_DONE))
- .WillOnce(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_int(_, _))
- .WillRepeatedly(Return(3));
int ret;
int cnt = 10;
int *w;
int *h;
- ret = widget_service_get_supported_sizes("org.tizen.test_widget", &cnt, &w, &h);
+ ret = widget_service_get_supported_sizes("org.tizen.gallery.widget", &cnt, &w, &h);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).Times(3)
- .WillOnce(Return(SQLITE_ROW))
- .WillOnce(Return(SQLITE_DONE))
- .WillOnce(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_int(_, _))
- .WillRepeatedly(Return(3));
int ret;
int cnt = 10;
int *types;
- ret = widget_service_get_supported_size_types("org.tizen.test_widget", &cnt, &types);
+ ret = widget_service_get_supported_size_types("org.tizen.gallery.widget", &cnt, &types);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
cb_data.data = NULL;
cb_data.cnt = 0;
- ret = widget_service_get_widget_instance_list("org.tizen.test_widget",
+ ret = widget_service_get_widget_instance_list("org.tizen.gallery.widget",
_widget_instance_list_cb, &cb_data);
ASSERT_TRUE(ret > 0);
}
int ret;
- ret = widget_service_set_lifecycle_event_cb("org.tizen.test_widget",
+ ret = widget_service_set_lifecycle_event_cb("org.tizen.gallery.widget",
_widget_lifecycle_event_cb, NULL);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
int ret;
- ret = widget_service_unset_lifecycle_event_cb("org.tizen.test_widget", NULL);
+ ret = widget_service_unset_lifecycle_event_cb("org.tizen.gallery.widget", NULL);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
.WillRepeatedly(Invoke(__fake_cynara_finish));
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_column_int(_, _))
- .WillRepeatedly(Return(3));
int ret;
- ret = widget_service_get_widget_max_count("org.tizen.test_widget");
+ ret = widget_service_get_widget_max_count("org.tizen.gallery.widget");
ASSERT_EQ(ret, 3);
}
int ret;
- ret = widget_service_get_instance_count("org.tizen.test_widget", NULL, NULL);
+ ret = widget_service_get_instance_count("org.tizen.gallery.widget", NULL, NULL);
ASSERT_EQ(ret, WIDGET_ERROR_NONE);
}
#include "include/widget_service_internal.h"
#include "aul_mock.h"
-#include "sqlite3_mock.h"
#include "system_info_mock.h"
#include "tzplatform_config_mock.h"
#include "test_fixture.h"
+#include "widget_plugin_parser.hh"
+#include "widget_plugin_parser_error.h"
using ::testing::_;
using ::testing::DoAll;
return 0;
}
+constexpr char XML1[] = R"__widget(<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="5.5" package="org.tizen.gallery_common" version="1.0.0">
+ <profile name="tizeniot"/>
+ <profile name="mobile"/>
+ <ui-application appid="org.tizen.gallery" exec="gallery" hw-acceleration="on" multiple="false" nodisplay="false" process-pool="true" taskmanage="true" type="capp">
+ <label>Gallery</label>
+ <label xml:lang="en-us">Gallery</label>
+ <icon>org.tizen.gallery.png</icon>
+ </ui-application>
+ <privileges>
+ <privilege>http://tizen.org/privilege/mediastorage</privilege>
+ <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ <privilege>http://tizen.org/privilege/externalstorage</privilege>
+ <privilege>http://tizen.org/privilege/content.write</privilege>
+ <privilege>http://tizen.org/privilege/appdir.shareddata</privilege>
+ </privileges>
+ <widget-application appid="org.tizen.gallery.widget" exec="gallery-widget" hw-acceleration="on" main="true" update-period="0">
+ <label>Gallery</label>
+ <label xml:lang="fr-fr">Galerie</label>
+ <icon>preview_gallery_4x4.png</icon>
+ <support-size preview="preview_gallery_4x4.png">4x4</support-size>
+ </widget-application>
+</manifest>
+)__widget";
+
class Mocks : virtual public ::testing::NiceMock<AulMock>,
- virtual public ::testing::NiceMock<SqlMock>,
virtual public ::testing::NiceMock<SystemInfoMock>,
virtual public ::testing::NiceMock<TzplatformConfigMock> {};
class WidgetInstanceTest : public TestFixture {
public:
WidgetInstanceTest() : TestFixture(std::make_unique<::Mocks>()) {}
+
void SetUp() override {
- table_ = (char** )calloc(10, sizeof(char*));
- db_ = (sqlite3*) table_;
+ EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
+ .WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
+
+ int ret = widget_service_check_db_integrity(false);
+ ASSERT_EQ(ret, WIDGET_ERROR_NONE);
+
+ widget_service::parser::WidgetPluginParser parser;
+ auto* doc = xmlParseDoc((xmlChar*)XML1);
+ ret = parser.ParseManifest(doc);
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
+
+ ret = parser.Insert("org.tizen.gallery_common");
+ ASSERT_EQ(ret, WIDGET_PARSER_ERROR_NONE);
}
+
void TearDown() override {
- free(table_);
+ remove(".widget_test.db");
}
- char** table_;
- sqlite3* db_;
};
TEST_F(WidgetInstanceTest, InstanceInit) {
int ret;
- ret = widget_instance_init("org.tizen.test_viewer");
+ ret = widget_instance_init("org.tizen.gallery.widget");
ASSERT_EQ(ret, 0);
}
TEST_F(WidgetInstanceTest, InstanceCreate) {
EXPECT_CALL(GetMock<TzplatformConfigMock>(), tzplatform_mkpath(_, _))
.WillRepeatedly(Invoke(__fake_tzplatform_mkpath));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_open_v2(_, _, _, _)).
- WillRepeatedly(DoAll(SetArgPointee<1>(db_), (Return(0))));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_prepare_v2(_, _, _, _, _)).WillRepeatedly(Return(0));
- EXPECT_CALL(GetMock<SqlMock>(),
- sqlite3_step(_)).WillRepeatedly(Return(SQLITE_ROW));
-
int ret = 0;
- ret = widget_instance_create("org.tizen.test_widget", &instance_id);
+ ret = widget_instance_create("org.tizen.gallery.widget", &instance_id);
ASSERT_EQ(ret, 0);
}
TEST_F(WidgetInstanceTest, InstanceForeach) {
int ret = 0;
- ret = widget_instance_foreach("org.tizen.test_widget", _widget_instance_foreach_cb, NULL);
+ ret = widget_instance_foreach("org.tizen.gallery.widget",
+ _widget_instance_foreach_cb, NULL);
ASSERT_EQ(ret, 0);
}
TEST_F(WidgetInstanceTest, InstanceGetInstance) {
widget_instance_h instance = nullptr;
- instance = widget_instance_get_instance("org.tizen.test_widget", instance_id);
+ instance = widget_instance_get_instance("org.tizen.gallery.widget",
+ instance_id);
ASSERT_NE(instance, nullptr);
ins = instance;
TEST_F(WidgetInstanceTest, InstanceGetList) {
int ret = 0;
- ret = widget_instance_get_instance_list("org.tizen.test_widget", _widget_instance_list_cb, NULL);
+ ret = widget_instance_get_instance_list("org.tizen.gallery.widget",
+ _widget_instance_list_cb, NULL);
ASSERT_EQ(ret, 0);
}
int ret = 0;
- ret = widget_instance_change_period("org.tizen.test_widget", instance_id, 5.0);
+ ret = widget_instance_change_period("org.tizen.gallery.widget",
+ instance_id, 5.0);
ASSERT_EQ(ret, 0);
}
int ret = 0;
- ret = widget_instance_listen_status("org.tizen.test_widget", _widget_instance_event_cb, NULL);
+ ret = widget_instance_listen_status("org.tizen.gallery.widget",
+ _widget_instance_event_cb, NULL);
ASSERT_EQ(ret, 0);
}
TEST_F(WidgetInstanceTest, InstanceUnlistenStatus) {
int ret = 0;
- ret = widget_instance_unlisten_status("org.tizen.test_widget");
+ ret = widget_instance_unlisten_status("org.tizen.gallery.widget");
ASSERT_EQ(ret, 0);
}
int ret = 0;
- ret = widget_instance_trigger_update_v2("org.tizen.test_widget", instance_id, "ContetnInfo", 1);
+ ret = widget_instance_trigger_update_v2("widget_instance_unlisten_status",
+ instance_id, "ContetnInfo", 1);
ASSERT_EQ(ret, 0);
}