diff options
author | Kibum Kim <kb0929.kim@samsung.com> | 2012-02-27 21:16:50 +0900 |
---|---|---|
committer | Kibum Kim <kb0929.kim@samsung.com> | 2012-02-27 21:16:50 +0900 |
commit | 615ac89e41f56c38e75ecb6e243480b87698c114 (patch) | |
tree | f0d4f0bd3d0c13c91a62a261b6ca6d36cc58daaf | |
download | wrt-installer-615ac89e41f56c38e75ecb6e243480b87698c114.tar.gz wrt-installer-615ac89e41f56c38e75ecb6e243480b87698c114.tar.bz2 wrt-installer-615ac89e41f56c38e75ecb6e243480b87698c114.zip |
tizen beta release
149 files changed, 18694 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d97a407 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,82 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# +# @file CMakeLists.txt +# @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) +# @brief +# + +############################# Check minimum CMake version ##################### + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(CMAKE_EDIT_COMMAND vim) +PROJECT("wrt-installer") + +############################# cmake packages ################################## + +INCLUDE(FindPkgConfig) + +############################# compilation defines ############################# + +# EMPTY + +############################# compiler flags ################################## + +SET(CMAKE_C_FLAGS_PROFILING "-O0 -g -pg") +SET(CMAKE_CXX_FLAGS_PROFILING "-O0 -std=c++0x -g -pg") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -std=c++0x -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2 -g") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -std=c++0x -g") + +# If supported for the target machine, emit position-independent code,suitable +# for dynamic linking and avoiding any limit on the size of the global offset +# table. This option makes a difference on the m68k, PowerPC and SPARC. +# (BJ: our ARM too?) +ADD_DEFINITIONS("-fPIC") + +ADD_DEFINITIONS("-DSEPARATED_SINGLETON_IMPLEMENTATION") + +# Set the default ELF image symbol visibility to hidden - all symbols will be +# marked with this unless overridden within the code. +#ADD_DEFINITIONS("-fvisibility=hidden") + +# Set compiler warning flags +#ADD_DEFINITIONS("-Werror") # Make all warnings into errors. +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings +ADD_DEFINITIONS("-Wno-variadic-macros") # Inhibit variadic macros warnings (needed for ORM) +ADD_DEFINITIONS("-Wno-deprecated") # No warnings about deprecated features +ADD_DEFINITIONS("-std=c++0x") # No warnings about deprecated features + +# Set Logs +OPTION(DPL_LOG "DPL logs status" ON) +IF(DPL_LOG) + MESSAGE(STATUS "Logging enabled for DPL") + ADD_DEFINITIONS("-DDPL_LOGS_ENABLED") +ELSE(DPL_LOG) + MESSAGE(STATUS "Logging disabled for DPL") +ENDIF(DPL_LOG) + +############################# Targets names ################################### + +SET(TARGET_INSTALLER_STATIC "wrt-installer_static") +SET(TARGET_INSTALLER "wrt-installer") +SET(TARGET_BACKEND_LIB "wgt") +SET(TARGET_CONFIG_GEN_LIB "wrt-config-generator") + +############################# subdirectories ################################## + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(tests)
\ No newline at end of file diff --git a/debian/DESCRIPTION b/debian/DESCRIPTION new file mode 100644 index 0000000..2b8a593 --- /dev/null +++ b/debian/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Debian folder (rules, control etc.) diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..87600b7 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,26 @@ +wrt-installer (0.0.10) unstable; urgency=low + + * Boilerplate update + + * Git : tizen2/pkgs/w/wrt-installer + * Tag : wrt-installer_0.0.10 + + -- Tae-Jeong Lee <taejeong.lee@samsung.com> Thu, 23 Feb 2012 16:14:18 +0900 + +wrt-installer (0.0.9) unstable; urgency=low + + * debianize + + * Git : tizen2/pkgs/w/wrt-installer + * Tag : wrt-installer_0.0.9 + + -- Yunchan Cho <yunchan.cho@samsung.com> Wed, 22 Feb 2012 16:55:58 +0900 + +wrt-installer (0.0.8) unstable; urgency=low + + * Init changelog + + * Git : tizen2/pkgs/w/wrt-installer + * Tag : wrt-installer_0.0.8 + + -- Jihoon Chung <jihoon.chung@samsung.com> Wed, 15 Feb 2012 13:40:40 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..a606c26 --- /dev/null +++ b/debian/control @@ -0,0 +1,25 @@ +Source: wrt-installer +Section: devel +Priority: extra +Maintainer: Krzysztof Jackiewicz<k.jackiewicz@samsung.com>, Bartlomiej Grzelewski<b.grzelewski@samsung.com>, jihoon Chung <jihoon.chung@samsung.com>, yunchan Cho <yunchan.cho@samsung.com> +Uploaders: Lukasz Wrzosek <l.wrzosek@samsung.com>, Grzegorz Krawczyk <g.krawczyk@samsung.com>, Soyoung Kim <sy037.kim@samsung.com>,Pawel Sikorski <p.sikorski@samsung.com>, Zbigniew Kostrzewa <z.kostrzewa@samsung.com> +Build-Depends: debhelper (>= 5), libglib2.0-dev, libsqlite3-dev, libwebkit-engine-dev, libelm-webview-dev, libxml2-dev, libdbus-1-dev, libefreet-dev, libappcore-efl-dev, openssl (>= 0.9.7), libcert-svc-dev, wrt-commons-dev (>= 0.2.15), libpcre-dev, libelm-dev, libecore-dev, libeina-dev, libui-gadget-dev, libslp-utilx-dev, libsecurity-server-client-dev, libpkgmgr-installer-dev, libxmlsec1-dev, libidn11-dev, libpkgmgr-types-dev, libss-client-dev, libiri-dev +Standards-Version: 0.0.1 + +Package: wrt-installer +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, ${misc:Depends}, openssl, libug-picker-efl +Replaces: wrt-installer +Provides: wrt-installer +Conflicts: wrt-installer +Description: online widget(W3C, BONDI, JIL, MSC) platform + +Package: wrt-installer-dbg +Architecture: any +Replaces: wrt-installer-dbg +Provides: wrt-installer-dbg +Conflicts: wrt-installer-dbg +Section: debug +Depends: ${shlibs:Depends}, ${misc:Depends}, wrt (= ${Source-Version}) +Description: online widget(W3C, BONDI, JIL, MSC) platform - debug diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..e772481 --- /dev/null +++ b/debian/dirs @@ -0,0 +1 @@ +usr/bin diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/docs diff --git a/debian/jobs b/debian/jobs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/jobs diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..af33220 --- /dev/null +++ b/debian/rules @@ -0,0 +1,126 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +PACKAGE_VERSION ?= $(shell sed -n "1 p" debian/changelog | sed 's/.*(\(.*\)).*/\1/') + +PREFIX ?= /usr +DATADIR ?= /opt +LDFLAGS = -Wl,--rpath=$(PREFIX)/lib +# Please set CFLAGS only in CMakeLists.txt, as they are dependent on CMake build type. + + +ifeq (,$(findstring no,$(DPL_LOG))) + DPL_LOGS_STATUS = "ON" +else + DPL_LOGS_STATUS = "OFF" +endif + +ifeq (1,$(WRT_SKIP_ACE_SUPPORT)) + WRT_SKIP_ACE = "ON" +else + WRT_SKIP_ACE = "OFF" +endif + +ifeq (1,$(WRT_SMACK_ENABLE)) + SMACK_STATUS = "ON" +else + SMACK_STATUS = "OFF" +endif + +#for building with: +#efl library, use TARGET=X1 +export TARGET=X1 + +CMAKE_BUILD_DIR ?= $(CURDIR)/cmake_build_tmp + +#config.status: configure +config.status: + dh_testdir + # Add here commands to configure the package. + mkdir -p $(CMAKE_BUILD_DIR) && cd $(CMAKE_BUILD_DIR) && \ + cmake ${SRCDIR} -DBUILD_TYPE="${TARGET}" -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DCMAKE_BUILD_TYPE="$(BUILD_TYPE)" -DDPL_LOG=$(DPL_LOGS_STATUS) -DSMACK_ENABLED=${SMACK_STATUS} -DCMAKE_PACKAGE_VERSION="$(PACKAGE_VERSION)" -DWRT_SKIP_ACE_SUPPORT="${WRT_SKIP_ACE}" .. + + +build: build-stamp + +build-stamp: config.status + dh_testdir + # Add here commands to compile the package. + cd $(CMAKE_BUILD_DIR) && $(MAKE) -j 4 + #docbook-to-man debian/ncurses.sgml > ncurses.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + rm -rf $(CMAKE_BUILD_DIR) + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/ncurses. + cd $(CMAKE_BUILD_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip --dbg-package=wrt-installer-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/debian/wrt-installer-dev.install.in b/debian/wrt-installer-dev.install.in new file mode 100644 index 0000000..86cd4f5 --- /dev/null +++ b/debian/wrt-installer-dev.install.in @@ -0,0 +1,2 @@ +@PREFIX@/include/wrt-security/* +@PREFIX@/include/config_generator/* diff --git a/debian/wrt-installer.install.in b/debian/wrt-installer.install.in new file mode 100644 index 0000000..6a9bf3e --- /dev/null +++ b/debian/wrt-installer.install.in @@ -0,0 +1,4 @@ +@PREFIX@/bin/* +@PREFIX@/lib/* +@PREFIX@/etc/* +/opt/apps/config_gen/* diff --git a/debian/wrt-installer.postinst b/debian/wrt-installer.postinst new file mode 100755 index 0000000..3b16852 --- /dev/null +++ b/debian/wrt-installer.postinst @@ -0,0 +1,8 @@ +#!/bin/sh + +chmod +s /usr/bin/wrt-installer + +#symlink for package manager +ln -sf /usr/bin/wrt-installer /usr/etc/package-manager/backend/wgt + +echo "[WRT-INSTALLER] wrt-installer postinst done ..." diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3a3281f --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,146 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# +# +# @file CMakeLists.txt +# @author Lukasz Wrzosek (l.wrzosek@samsung.com) +# @version 1.0 +# + +SET(TARGET_INSTALLER "wrt-installer") + +SET(INSTALLER_SRC_DIR + ${PROJECT_SOURCE_DIR}/src + ) + +SET(INSTALLER_CONFIG_PARSER + ${INSTALLER_SRC_DIR}/configuration_parser + ) + +SET(INSTALLER_JOBS + ${INSTALLER_SRC_DIR}/jobs + ) + +SET(INSTALLER_SECURITY + ${INSTALLER_SRC_DIR}/security + ) + +SET(INSTALLER_DEP_CORE_BASE_SOURCE + ${INSTALLER_SECURITY}/attribute_facade.cpp + ${INSTALLER_SECURITY}/simple_roaming_agent.cpp + ${INSTALLER_SECURITY}/security_controller.cpp + ${INSTALLER_SECURITY}/security_logic.cpp + ) + +SET(INSTALLER_INCLUDES + ${INSTALLER_SRC_DIR} + ${INSTALLER_SRC_DIR}/logic + ${INSTALLER_SRC_DIR}/jobs + ${INSTALLER_SRC_DIR}/jobs/plugin_install + ${INSTALLER_SRC_DIR}/jobs/widget_install + ${INSTALLER_SRC_DIR}/jobs/widget_uninstall + ${INSTALLER_SRC_DIR}/misc + ${INSTALLER_SRC_DIR}/configuration_parser + ${INSTALLER_SRC_DIR}/wrt-installer + ${INSTALLER_SRC_DIR}/security + ${INSTALLER_SRC_DIR}/commons +) + +SET(INSTALLER_SOURCES + ${INSTALLER_CONFIG_PARSER}/widget_parser.cpp + ${INSTALLER_CONFIG_PARSER}/parser_runner.cpp + ${INSTALLER_CONFIG_PARSER}/ignoring_parser.cpp + ${INSTALLER_CONFIG_PARSER}/deny_all_parser.cpp + ${INSTALLER_CONFIG_PARSER}/powder_parser.cpp + ${INSTALLER_CONFIG_PARSER}/libiriwrapper.cpp + ${INSTALLER_CONFIG_PARSER}/WidgetConfigurationManager.cpp + ${INSTALLER_JOBS}/job.cpp + ${INSTALLER_JOBS}/plugin_install/job_plugin_install.cpp + ${INSTALLER_JOBS}/plugin_install/plugin_install_task.cpp + ${INSTALLER_JOBS}/plugin_install/plugin_objects.cpp + ${INSTALLER_JOBS}/plugin_install/plugin_metafile_reader.cpp + ${INSTALLER_JOBS}/widget_install/job_widget_install.cpp + ${INSTALLER_JOBS}/widget_install/task_unzip.cpp + ${INSTALLER_JOBS}/widget_install/task_widget_config.cpp + ${INSTALLER_JOBS}/widget_install/task_db_update.cpp + ${INSTALLER_JOBS}/widget_install/task_smack.cpp + ${INSTALLER_JOBS}/widget_install/task_ace_check.cpp + ${INSTALLER_JOBS}/widget_install/task_desktop_file.cpp + ${INSTALLER_JOBS}/widget_install/task_parental_mode.cpp + ${INSTALLER_JOBS}/widget_install/task_certify.cpp + ${INSTALLER_JOBS}/widget_install/task_private_storage.cpp + ${INSTALLER_JOBS}/widget_install/wac_security.cpp + ${INSTALLER_JOBS}/widget_install/widget_update_info.cpp + ${INSTALLER_JOBS}/widget_uninstall/job_widget_uninstall.cpp + ${INSTALLER_JOBS}/widget_uninstall/task_check.cpp + ${INSTALLER_JOBS}/widget_uninstall/task_remove_files.cpp + ${INSTALLER_JOBS}/widget_uninstall/task_db_update.cpp + ${INSTALLER_JOBS}/widget_uninstall/task_smack.cpp + ${INSTALLER_SRC_DIR}/logic/installer_logic.cpp + ${INSTALLER_SRC_DIR}/logic/installer_controller.cpp + ${INSTALLER_SRC_DIR}/misc/wrt_powder_info_util.cpp + ${INSTALLER_SRC_DIR}/misc/wac_widget_id.cpp + ${INSTALLER_SRC_DIR}/misc/feature_logic.cpp + ) + +MESSAGE(STATUS "add -DSEP_INSTALLER") +ADD_DEFINITIONS("-DSEP_INSTALLER") + + +PKG_CHECK_MODULES(INSTALLER_STATIC_DEP + libxml-2.0 + openssl + dpl-efl + dpl-vcore + dpl-event-efl + dpl-utils-efl + dpl-popup-efl + dpl-wrt-dao-ro + dpl-wrt-dao-rw + dpl-ace + dpl-ace-dao-ro + dpl-ace-dao-rw + ecore-x + elm-webview + xmlsec1 + libidn + libiri + libpcrecpp + REQUIRED + ) + +INCLUDE_DIRECTORIES( + ${INSTALLER_DEP_INCLUDES} + ${INSTALLER_INCLUDES} + ${INSTALLER_STATIC_DEP_INCLUDE_DIRS} + ) + +ADD_LIBRARY(${TARGET_INSTALLER_STATIC} STATIC + ${INSTALLER_DEP_CORE_BASE_SOURCE} + ${INSTALLER_SOURCES} + ) + +ADD_DEFINITIONS(${INSTALLER_STATIC_DEP_CFLAGS}) +ADD_DEFINITIONS(${INSTALLER_STATIC_DEP_CFLAGS_OTHERS}) + +TARGET_LINK_LIBRARIES(${TARGET_INSTALLER_STATIC} + ${INSTALLER_STATIC_DEP_LIBRARIES} + ) + +SET_TARGET_PROPERTIES(${TARGET_INSTALLER_STATIC} PROPERTIES + COMPILE_FLAGS -fPIC) + +ADD_SUBDIRECTORY(pkg-manager) +ADD_SUBDIRECTORY(wrt-installer) +ADD_SUBDIRECTORY(config_generator) diff --git a/src/DESCRIPTION b/src/DESCRIPTION new file mode 100644 index 0000000..0e8c571 --- /dev/null +++ b/src/DESCRIPTION @@ -0,0 +1,2 @@ +!!!options!!! stop +Widget (un)installer, plugin (un)installer diff --git a/src/commons/wrt_common_types.h b/src/commons/wrt_common_types.h new file mode 100644 index 0000000..9b80c8a --- /dev/null +++ b/src/commons/wrt_common_types.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * plugin_common_types.h + * + * Author: Soyoung Kim(sy037.kim@samsung.com) + */ + +#ifndef PLUGIN_COMMON_TYPES_H +#define PLUGIN_COMMON_TYPES_H + +#include <dpl/utils/widget_version.h> +#include <dpl/wrt-dao-ro/common_dao_types.h> + +/** +* Widget version is optional +*/ +typedef DPL::Optional<WidgetVersion> OptionalWidgetVersion; + + +/* Define db type */ +typedef WrtDB::DbWidgetHandle WidgetHandle; +typedef WrtDB::DbWidgetHandleList WidgetHandleList; + +typedef WrtDB::DbWidgetFeature WidgetFeature; +typedef WrtDB::DbWidgetFeatureSet WidgetFeatureSet; + +typedef WrtDB::DbWidgetSize WidgetSize; + +typedef WrtDB::DbPluginHandle PluginHandle; + +#endif /* PLUGIN_COMMON_TYPES_H */ diff --git a/src/commons/wrt_error.h b/src/commons/wrt_error.h new file mode 100644 index 0000000..5a1960a --- /dev/null +++ b/src/commons/wrt_error.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * This file contains the declaration of the error codes of Widget. + * + * @file wrt_error.h + * @author MaQuan (jason.ma@samsung.com) + * @version 0.7 + * @brief This file contains the declaration of the error codes of Widget. + */ + +#ifndef _WRT_ERROR_H_ +#define _WRT_ERROR_H_ + +#ifndef WRT_ERROR_MASKL8 +#define WRT_ERROR_MASKL8 0xFF +#endif + +#ifndef WRT_SET_IDENT +#define WRT_SET_IDENT(X) (X & WRT_ERROR_MASKL8) +#endif + +#ifndef WRT_ERROR_SET +#define WRT_ERROR_SET(X) ((X & WRT_ERROR_MASKL8) << 8) +#endif + +#define WRT_MID_ERRCODE 0x10000 + WRT_SET_IDENT(5) + +/*typedef */ enum +{ + WRT_GENERAL_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(0), + WRT_CONFIG_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(1), + WRT_DOMAIN_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(2), + WRT_JS_EXT_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(3), + WRT_WM_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(4), + WRT_PLUGIN_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(5), + //_ACE support + WRT_SAI_ERRCODE = WRT_MID_ERRCODE + WRT_SET_IDENT(6) +}; + +/** + * WRT error code description + * + * @ WRT_SUCCESS + * There is no error with WRT operations. + * + * @ WRT_ERR_UNKNOW + * An unknow error happened to WRT. + * + * @ WRT_ERR_INVALID_ARG + * Invalid arguments are passed into WRT functions. + * + * @ WRT_ERR_OUT_MEMORY + * No memory space available for WRT. + * + * @ WRT_ERR_NO_DISK_SPACE + * There is no disk space for widget applications. + * + * + * + * + */ +enum WrtError +{ + /* General errors */ + WRT_SUCCESS = WRT_GENERAL_ERRCODE + WRT_ERROR_SET(0x01), + WRT_ERR_UNKNOWN = WRT_GENERAL_ERRCODE + WRT_ERROR_SET(0x02), + WRT_ERR_INVALID_ARG = WRT_GENERAL_ERRCODE + WRT_ERROR_SET(0x03), + WRT_ERR_OUT_OF_MEMORY = WRT_GENERAL_ERRCODE + WRT_ERROR_SET(0x04), + WRT_ERR_NO_DISK_SPACE = WRT_GENERAL_ERRCODE + WRT_ERROR_SET(0x05), + + /* Configuration */ + WRT_CONF_ERR_GCONF_FAILURE = WRT_CONFIG_ERRCODE + WRT_ERROR_SET(0x01), + WRT_CONF_ERR_OBJ_MISSING = WRT_CONFIG_ERRCODE + WRT_ERROR_SET(0x02), + WRT_CONF_ERR_OBJ_EXIST = WRT_CONFIG_ERRCODE + WRT_ERROR_SET(0x03), + WRT_CONF_ERR_START_FILE_MISSING = WRT_CONFIG_ERRCODE + WRT_ERROR_SET(0x04), + WRT_CONF_ERR_EMDB_FAILURE = WRT_CONFIG_ERRCODE + WRT_ERROR_SET(0x05), + WRT_CONF_ERR_EMDB_NO_RECORD = WRT_CONFIG_ERRCODE + WRT_ERROR_SET(0x06), + + /* Domain */ + WRT_DOMAIN_ERR_CREATE_JS_RT = WRT_DOMAIN_ERRCODE + WRT_ERROR_SET(0x01), + WRT_DOMAIN_ERR_MSG_QUEUE = WRT_DOMAIN_ERRCODE + WRT_ERROR_SET(0x02), + + /* Widget manager*/ + WRT_WM_ERR_NOT_INSTALLED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x01), + WRT_WM_ERR_HIGH_VER_INSTALLED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x02), + WRT_WM_ERR_LOW_VER_INSTALLED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x03), + WRT_WM_ERR_INVALID_ARCHIVE = WRT_WM_ERRCODE + WRT_ERROR_SET(0x04), + WRT_WM_ERR_INVALID_CERTIFICATION = WRT_WM_ERRCODE + WRT_ERROR_SET(0x05), + WRT_WM_ERR_NULL_CERTIFICATION = WRT_WM_ERRCODE + WRT_ERROR_SET(0x06), + WRT_WM_ERR_INSTALLATION_CANCEL = WRT_WM_ERRCODE + WRT_ERROR_SET(0x07), + WRT_WM_ERR_ALREADY_INSTALLED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x08), + WRT_WM_ERR_INSTALL_FAILED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x09), + WRT_WM_ERR_DELETE_BY_SERVER = WRT_WM_ERRCODE + WRT_ERROR_SET(0x0a), + WRT_WM_ERR_DEINSTALLATION_CANCEL = WRT_WM_ERRCODE + WRT_ERROR_SET(0x0b), + WRT_WM_ERR_INCORRECT_UPDATE_INFO = WRT_WM_ERRCODE + WRT_ERROR_SET(0x0c), + WRT_WM_ERR_UNREG_FAILED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x0d), + WRT_WM_ERR_REMOVE_FILES_FAILED = WRT_WM_ERRCODE + WRT_ERROR_SET(0x0e), + WRT_WM_ERR_ALREADY_LATEST = WRT_WM_ERRCODE + WRT_ERROR_SET(0x0f), + WRT_WM_ERR_UPDATE_CANCEL = WRT_WM_ERRCODE + WRT_ERROR_SET(0x10), + WRT_WM_ERR_IS_FACTORY_WIDGET = WRT_WM_ERRCODE + WRT_ERROR_SET(0x11), + WRT_WM_ERR_INVALID_APP_ID = WRT_WM_ERRCODE + WRT_ERROR_SET(0x12), + + /* Access Control Manager */ + WRT_SAI_ERR_INIT_ACE_FAILED = WRT_SAI_ERRCODE + WRT_ERROR_SET(0x01) +}; + +namespace CommonError { +enum Type +{ + WrtSuccess, ///< Success + + HandleNotFound, ///< Widget handle was not found + AlreadyRunning, ///< Widget is already running + AlreadyStopped, ///< Widget is already stopped + InvalidLanguage, ///< Widget is invalid in current locales + StillAuthorizing, ///< Widget is still autorizing and has not yet finished it + EarlyKilled, ///< Widget was early killed during launch + AccessDenied, ///< Access denied from ACE + CertificateRevoked, ///< Some certificate was revoked. + /// Widget is not allowed to run. + + Unknown ///< Temporary error. Try to not use this. +}; +} +#endif /* _WRT_ERROR_H_ */ + diff --git a/src/config_generator/CMakeLists.txt b/src/config_generator/CMakeLists.txt new file mode 100644 index 0000000..72b2066 --- /dev/null +++ b/src/config_generator/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# + +INCLUDE(FindPkgConfig) + +PKG_CHECK_MODULES(CONFIG_GEN_DEPS + libxml-2.0 + dpl-efl + REQUIRED) + +SET(CONFIG_GEN_SOURCES + config_generator.cpp) + +INCLUDE_DIRECTORIES(${CONFIG_GEN_DEPS_INCLUDE_DIRS}) + +ADD_LIBRARY(${TARGET_CONFIG_GEN_LIB} SHARED + ${CONFIG_GEN_SOURCES}) + +SET_TARGET_PROPERTIES(${TARGET_CONFIG_GEN_LIB} PROPERTIES + SOVERSION ${CMAKE_PACKAGE_VERSION}) + +SET_TARGET_PROPERTIES(${TARGET_CONFIG_GEN_LIB} PROPERTIES + COMPILE_FLAGS -fPIC) + +TARGET_LINK_LIBRARIES(${TARGET_CONFIG_GEN_LIB} + ${CONFIG_GEN_DEPS_LIBRARIES}) + +INSTALL(TARGETS ${TARGET_CONFIG_GEN_LIB} + DESTINATION lib + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + +INSTALL(FILES + config_generator.h + DESTINATION include/config_generator)
\ No newline at end of file diff --git a/src/config_generator/config_generator.cpp b/src/config_generator/config_generator.cpp new file mode 100644 index 0000000..9efe644 --- /dev/null +++ b/src/config_generator/config_generator.cpp @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file config_generator.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "config_generator.h" +#include <sstream> +#include <dpl/binary_queue.h> +#include <dpl/log/log.h> +#include <dpl/foreach.h> +#include <libxml/xmlversion.h> +#include <libxml/xmlstring.h> +#include <libxml/tree.h> + +namespace ConfigXml { + +class XmlDocWrapper { +public: + XmlDocWrapper(xmlDocPtr doc) : m_doc(doc) {} + ~XmlDocWrapper() { xmlFreeDoc(m_doc); } + xmlDocPtr get() const { return m_doc; } + +private: + xmlDocPtr m_doc; +}; + +class XmlNodeWrapper { +public: + XmlNodeWrapper(xmlNodePtr node) : m_node(node) {} + xmlNodePtr get() const { return m_node; } + +private: + // not owned + xmlNodePtr m_node; +}; + +namespace { + +// helper strings +const xmlChar* _DOC_VERSION_ = BAD_CAST "1.0"; +const xmlChar* _WIDGET_ = BAD_CAST "widget"; +const xmlChar* _SRC_ = BAD_CAST "src"; +const xmlChar* _REQUIRED_ = BAD_CAST "required"; +const xmlChar* _TRUE_ = BAD_CAST "true"; +const xmlChar* _FALSE_ = BAD_CAST "false"; +const xmlChar* _NAME_ = BAD_CAST "name"; +const xmlChar* _VALUE_ = BAD_CAST "value"; +const xmlChar* _XMLNS_ = BAD_CAST "xmlns"; +const xmlChar* _NAMESPACE_ = BAD_CAST "http://www.w3.org/ns/widgets"; +const xmlChar* _ID_ = BAD_CAST "id"; +const xmlChar* _VERSION_ = BAD_CAST "version"; +const xmlChar* _HEIGHT_ = BAD_CAST "height"; +const xmlChar* _WIDTH_ = BAD_CAST "width"; +const xmlChar* _VIEWMODES_ = BAD_CAST "viewmodes"; +const xmlChar* _ORIGIN_ = BAD_CAST "origin"; +const xmlChar* _SUBDOMAINS_ = BAD_CAST "subdomains"; +const xmlChar* _HREF_ = BAD_CAST "href"; +const xmlChar* _EMAIL_ = BAD_CAST "email"; +const xmlChar* _READONLY_ = BAD_CAST "readonly"; + +struct TagInfo { + const xmlChar* name; // Tag name + const Tag parent; // Tag parent +}; + +const TagInfo TAG[TAG_COUNT] = { + {BAD_CAST "widget", INVALID}, + {BAD_CAST "name", WIDGET}, + {BAD_CAST "icon", WIDGET}, + {BAD_CAST "content", WIDGET}, + {BAD_CAST "author", WIDGET}, + {BAD_CAST "license", WIDGET}, + {BAD_CAST "feature", WIDGET}, + {BAD_CAST "param", FEATURE}, + {BAD_CAST "description", WIDGET}, + {BAD_CAST "preference", WIDGET}, + {BAD_CAST "access", WIDGET}, + {BAD_CAST "tizen:setting", WIDGET} +}; + +// helper functions +xmlNodePtr NewNode(xmlNodePtr parent, Tag tagId) +{ + LogDebug("Adding node " << TAG[tagId].name); + + // check parent + Assert(0==xmlStrcmp(parent->name,TAG[TAG[tagId].parent].name) && + "Wrong parent"); + + xmlNodePtr node = xmlNewNode(NULL, TAG[tagId].name); + if (NULL == node) { + Throw(NodeCreationError); + } + if (NULL == xmlAddChild(parent,node)) { + Throw(ChildCreationError); + } + return node; +} + +void AddProperty(xmlNodePtr node, const xmlChar* name, const xmlChar* value) +{ + if (!xmlNewProp(node, name, value)) { + Throw(PropertyCreationError); + } +} + +void AddBoolProp(xmlNodePtr node, const xmlChar* name, bool value) +{ + AddProperty(node, name, (value ? _TRUE_ : _FALSE_)); + +} + +void AddCharProp(xmlNodePtr node, const xmlChar* name, const char* value) +{ + if (value) { + AddProperty(node, name, BAD_CAST value); + } +} + +void AddCharProp(xmlNodePtr node, const char* name, const char* value) +{ + if (value) { + AddProperty(node, BAD_CAST name, BAD_CAST value); + } +} + +void AddNameAndValue(xmlNodePtr node, const char* name, const char* value) +{ + AddCharProp(node, _NAME_, name); + AddCharProp(node, _VALUE_, value); +} + +} // namespace + +// ELEMENT /////////////////////////////////////////////////////////////// + +// <tag>value</tag> +#define DECLARE_HANDLER_CONTENT(tag) \ +template <> \ +XmlNodeWrapperPtr Element::Handler<tag, const char*>::CreateNode( \ + const char* value) \ +{ \ + xmlNodePtr node = NewNode(m_parent->get(), tag); \ + xmlNodeSetContent(node, BAD_CAST value); \ + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); \ + return ret; \ +} + +// <tag src="value"></tag> +#define DECLARE_HANDLER_SRC_ATTRIBUTE(tag) \ +template <> \ +XmlNodeWrapperPtr Element::Handler<tag, const char*>::CreateNode( \ + const char* value) \ +{ \ + xmlNodePtr node = NewNode(m_parent->get(), tag); \ + AddCharProp(node, _SRC_, value); \ + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); \ + return ret; \ +} + +DECLARE_HANDLER_CONTENT(NAME); +DECLARE_HANDLER_CONTENT(DESCRIPTION); +DECLARE_HANDLER_SRC_ATTRIBUTE(ICON); +DECLARE_HANDLER_SRC_ATTRIBUTE(CONTENT); + +// <author href="href" email="email">author</author> +template <> +XmlNodeWrapperPtr Element:: + Handler<AUTHOR, const char*, const char*, const char*>:: + CreateNode(const char* href, const char* email, const char* author) +{ + xmlNodePtr node = NewNode(m_parent->get(), AUTHOR); + AddCharProp(node, _HREF_, href); + AddCharProp(node, _EMAIL_, email); + xmlNodeSetContent(node, BAD_CAST author); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <license href="href">license</license> +template <> +XmlNodeWrapperPtr Element::Handler<LICENSE, const char*, const char*>:: + CreateNode(const char* href, const char* license) +{ + xmlNodePtr node = NewNode(m_parent->get(), LICENSE); + AddCharProp(node, _HREF_, href); + xmlNodeSetContent(node, BAD_CAST license); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <feature name="value" required="true"></feature> +template <> +XmlNodeWrapperPtr Element::Handler<FEATURE, const char*, bool>::CreateNode( + const char* value, + bool required) +{ + xmlNodePtr node = NewNode(m_parent->get(), FEATURE); + AddCharProp(node, _NAME_, value); + AddBoolProp(node, _REQUIRED_, required); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <param name="name" value="true"></param> +template <> +XmlNodeWrapperPtr Element::Handler<PARAM, const char*, bool>::CreateNode( + const char* name, + bool value) +{ + xmlNodePtr node = NewNode(m_parent->get(), PARAM); + AddCharProp(node, _NAME_, name); + AddBoolProp(node, _VALUE_, value); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <param name="name" value="value"></param> +template <> +XmlNodeWrapperPtr Element::Handler<PARAM, const char*, const char*>::CreateNode( + const char* name, + const char* value) +{ + xmlNodePtr node = NewNode(m_parent->get(), PARAM); + AddNameAndValue(node, name, value); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <preference name="name" value="value"></preference> +template <> +XmlNodeWrapperPtr Element::Handler<PREFERENCE, const char*, const char*>:: + CreateNode(const char* name, const char* value) +{ + xmlNodePtr node = NewNode(m_parent->get(), PREFERENCE); + AddNameAndValue(node, name, value); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <preference name="name" value="value" readonly="true"></preference> +template <> +XmlNodeWrapperPtr Element::Handler<PREFERENCE, const char*, const char*, bool>:: + CreateNode(const char* name, const char* value, bool readonly) +{ + xmlNodePtr node = NewNode(m_parent->get(), PREFERENCE); + AddNameAndValue(node, name, value); + AddBoolProp(node, _READONLY_, readonly); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <access name="value"></access> +template <> +XmlNodeWrapperPtr Element::Handler<ACCESS, const char*>::CreateNode( + const char* value) +{ + xmlNodePtr node = NewNode(m_parent->get(), ACCESS); + AddCharProp(node, _ORIGIN_, value); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <access name="value" subdomains="true"></access> +template <> +XmlNodeWrapperPtr Element::Handler<ACCESS, const char*, bool>::CreateNode( + const char* value, + bool required) +{ + xmlNodePtr node = NewNode(m_parent->get(), ACCESS); + AddCharProp(node, _ORIGIN_, value); + AddBoolProp(node, _SUBDOMAINS_, required); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// <tizen:setting name="value"></tizen:setting> +template <> +XmlNodeWrapperPtr Element::Handler<TIZEN_SETTING, const char*, const char*>:: + CreateNode(const char* name, const char* value) +{ + xmlNodePtr node = NewNode(m_parent->get(), TIZEN_SETTING); + AddCharProp(node, name, value); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(node)); + return ret; +} + +// DOCUMENT ////////////////////////////////////////////////////////////// + +// <widget xmlns="value" id="id" viewmodes="viewmodes"></widget> +template <> +XmlNodeWrapperPtr Document:: + Handler<WIDGET, const char*, const char*, const char*>:: + CreateRoot(const char* id, const char* version, const char* viewmodes) +{ + Assert(NULL == xmlDocGetRootElement(m_document->get()) && + "The document already has root node"); + + // root + xmlNodePtr root = xmlNewNode(NULL, _WIDGET_); + if (NULL == root) { + Throw(NodeCreationError); + } + xmlDocSetRootElement(m_document->get(), root); + AddProperty(root, _XMLNS_, _NAMESPACE_ ); + AddCharProp(root, _ID_, id); + AddCharProp(root, _VERSION_, version); + AddCharProp(root, _VIEWMODES_, viewmodes); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(root)); + return ret; +} + +/* + * <widget xmlns="value" id="id" height="height" width="width" + * viewmodes="viewmodes"></widget> + */ +template <> +XmlNodeWrapperPtr Document:: + Handler<WIDGET, const char*, const char*, int, int>:: + CreateRoot(const char* id, const char* version, int height, int width) +{ + // root + xmlNodePtr root = xmlNewNode(NULL, _WIDGET_); + if (NULL == root) { + Throw(NodeCreationError); + } + xmlDocSetRootElement(m_document->get(), root); + AddProperty(root, _XMLNS_, _NAMESPACE_ ); + AddCharProp(root, _ID_, id); + AddCharProp(root, _VERSION_, version); + std::ostringstream hstream; + hstream << height; + AddProperty(root, _HEIGHT_, BAD_CAST hstream.str().c_str()); + std::ostringstream wstream; + wstream << width; + AddProperty(root, _WIDTH_, BAD_CAST wstream.str().c_str()); + XmlNodeWrapperPtr ret(new XmlNodeWrapper(root)); + return ret; +} + +DocumentPtr Document::Create() +{ + // check libxml version + LIBXML_TEST_VERSION; + + xmlDocPtr xmlDoc = xmlNewDoc(_DOC_VERSION_); + if( NULL == xmlDoc) { + Throw(DocCreationError); + } + + // document + XmlDocWrapperPtr document(new XmlDocWrapper(xmlDoc)); + + DocumentPtr doc(new Document(document)); + return doc; +} + +Document::~Document() +{ +} + +void Document::Write(DPL::AbstractOutput& output) +{ + // write + xmlChar* buffer = NULL; + + int size; + xmlDocDumpFormatMemory(m_document->get(), &buffer, &size, 1); + std::unique_ptr<xmlChar, xmlFreeFunc> bufferPtr(buffer, xmlFree); + + DPL::BinaryQueue bq; + bq.AppendCopy(static_cast<unsigned char*>(buffer), size); + output.Write(bq, bq.Size()); +} + +} // ConfigXml diff --git a/src/config_generator/config_generator.h b/src/config_generator/config_generator.h new file mode 100644 index 0000000..8e5e1fa --- /dev/null +++ b/src/config_generator/config_generator.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file config_generator.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef CONFIG_GENERATOR_H_ +#define CONFIG_GENERATOR_H_ + +#include <dpl/abstract_output.h> +#include <dpl/assert.h> +#include <dpl/exception.h> +#include <list> +#include <memory> + +namespace ConfigXml { + +enum Tag { + WIDGET = 0, + NAME, + ICON, + CONTENT, + AUTHOR, + LICENSE, + FEATURE, + PARAM, + DESCRIPTION, + PREFERENCE, + ACCESS, + TIZEN_SETTING, + + TAG_COUNT, + INVALID +}; + +/* + * TODO + * -Global attributes support xml:lang, dir + * -Children cardinality + * -Other... + */ + +DECLARE_EXCEPTION_TYPE(DPL::Exception, Base); +DECLARE_EXCEPTION_TYPE(Base, NodeCreationError); +DECLARE_EXCEPTION_TYPE(Base, DocCreationError); +DECLARE_EXCEPTION_TYPE(Base, ChildCreationError); +DECLARE_EXCEPTION_TYPE(Base, PropertyCreationError); + +// ELEMENT /////////////////////////////////////////////////////////// + +class Element; +typedef std::shared_ptr<Element> ElementPtr; + +class XmlNodeWrapper; +typedef std::shared_ptr<XmlNodeWrapper> XmlNodeWrapperPtr; + +class Element { +public: + template <Tag TagId, typename... Params> + ElementPtr Add(Params... parameters); + +private: + friend class Document; + + // helper class for handling nodes + template <Tag TagId,typename... Params> + class Handler { + public: + explicit Handler(XmlNodeWrapperPtr parent) : m_parent(parent) {} + + XmlNodeWrapperPtr CreateNode(Params... parameters); + private: + // not owned! + XmlNodeWrapperPtr m_parent; + }; + + explicit Element(XmlNodeWrapperPtr node) : m_node(node) + { + Assert(m_node); + } + + // not owned! + XmlNodeWrapperPtr m_node; +}; + +template <Tag TagId, typename... Params> +ElementPtr Element::Add(Params... parameters) +{ + Handler<TagId,Params...> eh(m_node); + ElementPtr e(new Element(eh.CreateNode(parameters...))); + return e; +} + + +// DOCUMENT ////////////////////////////////////////////////////////// + +class Document; +typedef std::shared_ptr<Document> DocumentPtr; + +class XmlDocWrapper; +typedef std::shared_ptr<XmlDocWrapper> XmlDocWrapperPtr; + +class Document { +public: + static DocumentPtr Create(); + + void Write(DPL::AbstractOutput& output); + + template <Tag TagId, typename... Params> + ElementPtr Add(Params... parameters); + + ~Document(); + +private: + explicit Document(XmlDocWrapperPtr document) : + m_document(document) + { + Assert(m_document); + } + + // helper class for handling root node + template <Tag TagId,typename... Params> + class Handler { + public: + explicit Handler(XmlDocWrapperPtr document) : m_document(document) {} + + XmlNodeWrapperPtr CreateRoot(const Params... parameters); + private: + // not owned! + XmlDocWrapperPtr m_document; + }; + + XmlDocWrapperPtr m_document; +}; + +template <Tag TagId, typename... Params> +ElementPtr Document::Add(Params... parameters) +{ + Handler<TagId,Params...> dh(m_document); + ElementPtr e(new Element(dh.CreateRoot(parameters...))); + return e; +} + +}; // ConfigXml + +#endif /* CONFIG_GENERATOR_H_ */ diff --git a/src/configuration_parser/WidgetConfigurationManager.cpp b/src/configuration_parser/WidgetConfigurationManager.cpp new file mode 100644 index 0000000..2441731 --- /dev/null +++ b/src/configuration_parser/WidgetConfigurationManager.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file WidgetConfigurationManager.cpp + * @author Piotr Fatyga (p.fatyga@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 0.1 + * @brief + */ +#include "WidgetConfigurationManager.h" +#include <dirent.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include "root_parser.h" +#include "parser_runner.h" +#include "widget_parser.h" +#include <wrt_error.h> +#include <dpl/utils/mime_type_utils.h> +#include <dpl/localization/w3c_file_localization.h> +#include <dpl/utils/wrt_utility.h> +#include <dpl/singleton_impl.h> +IMPLEMENT_SINGLETON(WidgetConfigurationManager) + +//TODO Rewrite this as steps/tasks +namespace // anonymous +{ +const char *const DEFAULT_LANGUAGE = "default"; +const size_t MAX_WIDGET_PATH_SIZE = 1024; + +//#define WRT_WIDGET_DEFAULT_ICON_WIDTH 80 +//#define WRT_WIDGET_DEFAULT_ICON_HEIGHT 80 + +//#define WRT_WIDGET_CONFIG_BASE_LOCALE "locales" +const char *const WRT_WIDGET_CONFIG_FILE_NAME = "config.xml"; +} + +bool WidgetConfigurationManager::locateAndParseConfigurationFile( + const std::string& _currentPath, + WrtDB::WidgetRegisterInfo& pWidgetConfigInfo, + const std::string& baseFolder, + int* pErrCode) +{ + using namespace WrtDB; + + if (!pErrCode) { + return false; + } + + //TODO: use DPL::String in the caller to this function too. + DPL::String currentPath = DPL::FromUTF8String(_currentPath); + + if (currentPath.empty() || baseFolder.empty()) { + *pErrCode = WRT_ERR_INVALID_ARG; + return false; + } + + //TODO: rewrite this madness + char cfgAbsPath[MAX_WIDGET_PATH_SIZE + 1] = { 0 }; + DIR* dir = NULL; + struct dirent* ptr = NULL; + std::string language = ""; + + dir = opendir(_currentPath.c_str()); + if (dir == NULL) { + *pErrCode = WRT_ERR_UNKNOWN; + return false; + } + + ConfigParserData& configInfo = pWidgetConfigInfo.configInfo; + + //TODO why don't we use fopen here + bool has_config_xml = false; + errno = 0; + while ((ptr = readdir(dir)) != NULL) { //Find configuration file, based on its name + if (ptr->d_type == DT_REG) { + if (!strcmp(ptr->d_name, WRT_WIDGET_CONFIG_FILE_NAME)) { + _WrtUtilSetAbsolutePath(cfgAbsPath, + _currentPath.c_str(), ptr->d_name); + //Parse widget configuration file + LogDebug("Found config: " << cfgAbsPath); + ParserRunner parser; + + Try + { + parser.Parse(cfgAbsPath, ElementParserPtr(new + RootParser< + WidgetParser>( + configInfo, + DPL + :: + FromUTF32String( + L"widget")))); + } + Catch(ElementParser::Exception::Base) + { + LogDebug("Invalid widget configuration file!"); + // _rethrown_exception.Dump(); + *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; + closedir(dir); + return false; + } + + // + // WidgetConfigurationParser & parser = WidgetConfigurationParserSingleton::Instance(); + // if (!parser.parseConfigurationFile(cfgAbsPath, configInfo, baseFolder.c_str(), pWidgetConfigInfo.signature_type)) { + // LogDebug("Invalid widget configuration file!"); + // *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; + // closedir(dir); + // return false; + // } + + has_config_xml = true; + break; + } + } + } + closedir(dir); + + //We must have config.xml so leaveing if we doesn't + if (!has_config_xml) { + LogDebug("Invalid archive"); + *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; + return false; + } + + char *tmp_language; + if (!_WrtUtilStringToLower(baseFolder.c_str(), &tmp_language)) { + *pErrCode = WRT_ERR_UNKNOWN; + return false; + } + + if (!tmp_language) { + *pErrCode = WRT_ERR_UNKNOWN; + return false; + } + language = tmp_language; + free(tmp_language); + + if (!!configInfo.widget_id) { + if (!pWidgetConfigInfo.guid) { + pWidgetConfigInfo.guid = configInfo.widget_id; + } else { + if (pWidgetConfigInfo.guid != configInfo.widget_id) { + *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; + LogDebug("Invalid archive"); + return false; + } + } + } + + if (!!configInfo.pkgname) { + if (!pWidgetConfigInfo.pkgname) { + pWidgetConfigInfo.pkgname = configInfo.pkgname; + } else { + if (pWidgetConfigInfo.pkgname != configInfo.pkgname) { + *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; + LogDebug("Invalid archive - Package Name not same error"); + return false; + } + } + } + + if (!!configInfo.version) { + if (!pWidgetConfigInfo.version) { + pWidgetConfigInfo.version = configInfo.version; + } else { + if (pWidgetConfigInfo.version != configInfo.version) { + *pErrCode = WRT_WM_ERR_INVALID_ARCHIVE; + LogDebug("Invalid archive"); + return false; + } + } + } + + return true; +} + +void WidgetConfigurationManager::processFile(const std::string& path, + WrtDB::WidgetRegisterInfo &widgetConfiguration) +{ + int pErrCode; + + if (!locateAndParseConfigurationFile(path, widgetConfiguration, + DEFAULT_LANGUAGE, &pErrCode)) { + LogWarning("Widget archive: Failed while parsing config file"); + ThrowMsg(Exception::ProcessFailed, path); + } +} diff --git a/src/configuration_parser/WidgetConfigurationManager.h b/src/configuration_parser/WidgetConfigurationManager.h new file mode 100644 index 0000000..fc0ac5e --- /dev/null +++ b/src/configuration_parser/WidgetConfigurationManager.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file WidgetConfigurationManager.h + * @author Piotr Fatyga (p.fatyga@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef _WIDGETCONFIGURATIONMANAGER_H +#define _WIDGETCONFIGURATIONMANAGER_H + +#include <dpl/singleton.h> +#include <dpl/string.h> +#include <dpl/optional.h> +#include <dpl/wrt-dao-ro/config_parser_data.h> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <list> + +class WidgetConfigurationManager +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ProcessFailed) + }; + + /** + * This method is used to process the config.xml of widget, get + * the corresponding configuration to pWidgetConfigInfo + * + * @param[in] path Specified the widget archive file path (absolute path). + * @return Configuration information of widget + */ + void processFile(const std::string& path, + WrtDB::WidgetRegisterInfo &wConfig); + + private: + typedef std::list<std::pair<DPL::String, DPL::String> > StringPairList; + + bool locateAndParseConfigurationFile(const std::string& currentPath, + WrtDB::WidgetRegisterInfo& pWidgetConfigInfo, + const std::string& baseFolder, + int* pErrCode); +}; + +typedef DPL::Singleton<WidgetConfigurationManager> +WidgetConfigurationManagerSingleton; + +#endif // _WIDGETCONFIGURATIONMANAGER_H diff --git a/src/configuration_parser/deny_all_parser.cpp b/src/configuration_parser/deny_all_parser.cpp new file mode 100644 index 0000000..cffa56a --- /dev/null +++ b/src/configuration_parser/deny_all_parser.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "deny_all_parser.h" +#include <dpl/assert.h> + +DenyAllParser::DenyAllParser() : ElementParser() +{ +} + +ElementParserPtr DenyAllParser::Create() +{ + ThrowMsg(Exception::ParseError, "There must not be any subelement"); +} + +ElementParser::ActionFunc DenyAllParser::GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) +{ + ThrowMsg(Exception::ParseError, "There must not be any subelement"); +} + +void DenyAllParser::Accept(const Element& /*element*/) +{ + ThrowMsg(Exception::ParseError, "There must not be any element"); +} + +void DenyAllParser::Accept(const XmlAttribute& /*attribute*/) +{ + ThrowMsg(Exception::ParseError, "There must not be any attribute"); +} + +void DenyAllParser::Accept(const Text& /*text*/) +{ + ThrowMsg(Exception::ParseError, "There must not be any text element"); +} diff --git a/src/configuration_parser/deny_all_parser.h b/src/configuration_parser/deny_all_parser.h new file mode 100644 index 0000000..2d45707 --- /dev/null +++ b/src/configuration_parser/deny_all_parser.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file deny_all_parser.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef DENY_ALL_PARSER_H +#define DENY_ALL_PARSER_H + +#include "element_parser.h" + +struct DenyAllParser : public ElementParser +{ + static ElementParserPtr Create(); + virtual void Accept(const Element& /*element*/); + virtual void Accept(const XmlAttribute& /*attribute*/); + virtual void Accept(const Text& /*text*/); + virtual void Verify() + { + } + virtual ActionFunc GetElementParser(const DPL::String& ns, + const DPL::String& name); + + DenyAllParser(); +}; + +#endif // DENY_ALL_PARSER_H diff --git a/src/configuration_parser/element_parser.h b/src/configuration_parser/element_parser.h new file mode 100644 index 0000000..50a74bb --- /dev/null +++ b/src/configuration_parser/element_parser.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file element_parser.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef ELEMENT_PARSER_H_ +#define ELEMENT_PARSER_H_ + +#include <map> +#include <string> +#include <cstring> +#include <dpl/fast_delegate.h> +#include <dpl/exception.h> +#include <dpl/optional.h> +#include <dpl/string.h> +#include <dpl/shared_ptr.h> +#include <dpl/enable_shared_from_this.h> + +struct XmlAttribute +{ + DPL::String name; + DPL::String value; + DPL::String ns; + DPL::String lang; +}; + +struct Element +{ + DPL::String name; + DPL::String value; + DPL::String ns; + DPL::String lang; +}; + +struct Text +{ + DPL::String value; + DPL::String ns; + DPL::String lang; +}; + +class ElementParser; + +typedef DPL::SharedPtr<ElementParser> ElementParserPtr; + +class ElementParser : public DPL::EnableSharedFromThis<ElementParser> +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, ParseError) + }; + typedef DPL::FastDelegate0<ElementParserPtr> ActionFunc; + typedef std::map<DPL::String, ActionFunc> FuncMap; + + virtual void Accept(const Element&) = 0; + virtual void Accept(const XmlAttribute&) = 0; + virtual void Accept(const Text&) = 0; + virtual void Verify() = 0; + virtual ActionFunc GetElementParser(const DPL::String &ns, + const DPL::String &name) = 0; + virtual ~ElementParser() + { + } + + protected: + ElementParser() + { + } +}; + +#endif // ELEMENT_PARSER_H_ diff --git a/src/configuration_parser/ignoring_parser.cpp b/src/configuration_parser/ignoring_parser.cpp new file mode 100644 index 0000000..a997f29 --- /dev/null +++ b/src/configuration_parser/ignoring_parser.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file ignoring_parser.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#include "ignoring_parser.h" + +IgnoringParser::IgnoringParser() : ElementParser() +{ +} + +ElementParserPtr IgnoringParser::Create() +{ + return ElementParserPtr(new IgnoringParser()); +} + +ElementParserPtr IgnoringParser::Reuse() +{ + return SharedFromThis(); +} + +ElementParser::ActionFunc IgnoringParser::GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) +{ + return DPL::MakeDelegate(this, &IgnoringParser::Reuse); +} + +void IgnoringParser::Accept(const Element& /*element*/) +{ +} + +void IgnoringParser::Accept(const Text& /*text*/) +{ +} + +void IgnoringParser::Accept(const XmlAttribute& /*attribute*/) +{ +} + +void IgnoringParser::Verify() +{ +} diff --git a/src/configuration_parser/ignoring_parser.h b/src/configuration_parser/ignoring_parser.h new file mode 100644 index 0000000..9f1f6d5 --- /dev/null +++ b/src/configuration_parser/ignoring_parser.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file ignoring_parser.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef IGNORING_PARSER_H_ +#define IGNORING_PARSER_H_ + +#include "element_parser.h" + +struct IgnoringParser : public ElementParser +{ + static ElementParserPtr Create(); + virtual ActionFunc GetElementParser(const DPL::String& ns, + const DPL::String& name); + virtual void Accept(const Element&); + virtual void Accept(const Text&); + virtual void Accept(const XmlAttribute&); + virtual void Verify(); + + IgnoringParser(); + + private: + ElementParserPtr Reuse(); +}; + +#endif // IGNORING_PARSER_H_ diff --git a/src/configuration_parser/libiriwrapper.cpp b/src/configuration_parser/libiriwrapper.cpp new file mode 100644 index 0000000..f429344 --- /dev/null +++ b/src/configuration_parser/libiriwrapper.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file libiriwrapper.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com + * @version 0.1 + * @brief Libiri parser wrapper + */ +#include <stdlib.h> +#include <iri.h> +#include "libiriwrapper.h" + +//TODO: Design and implement new IRI manager class + +namespace LibIri { +Wrapper::Wrapper(const char* aIri) : m_Iri(iri_parse(aIri)) +{ +} +Wrapper::~Wrapper() +{ + iri_destroy(m_Iri); +} +//! \brief Returns true if iri is valid +bool Wrapper::Validate() +{ + return + m_Iri != NULL && + m_Iri->scheme != NULL && ( + m_Iri->display != NULL || + m_Iri->user != NULL || + m_Iri->auth != NULL || + m_Iri->password != NULL || + m_Iri->host != NULL || + m_Iri->path != NULL || + m_Iri->query != NULL || + m_Iri->anchor != NULL || + m_Iri->qparams != NULL || + m_Iri->schemelist != NULL); +} + +std::ostream & operator<<(std::ostream& a_stream, + const Wrapper& a_wrapper) +{ + iri_t& iri = *a_wrapper.m_Iri; +#define PRINT_FIELD(field) "] " # field " [" << (iri.field ? iri.field : "null") + a_stream << + " display [" << (iri.display ? iri.display : "null") << + PRINT_FIELD(scheme) << + PRINT_FIELD(user) << + PRINT_FIELD(auth) << + PRINT_FIELD(password) << + PRINT_FIELD(host) << + "] port [" << (iri.port ? iri.port : -1) << + PRINT_FIELD(path) << + PRINT_FIELD(query) << + PRINT_FIELD(anchor) << + "]"; + return a_stream; +#undef PRINT_FIELD +} +} //namespace LibIri diff --git a/src/configuration_parser/libiriwrapper.h b/src/configuration_parser/libiriwrapper.h new file mode 100644 index 0000000..1029059 --- /dev/null +++ b/src/configuration_parser/libiriwrapper.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file libiriwrapper.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com + * @version 0.1 + * @brief Libiri parser wrapper + */ + +#ifndef _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_LIBIRIWRAPPER_H_ +#define _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_LIBIRIWRAPPER_H_ + +#include <iostream> +#include <iri.h> + +//TODO: Design and implement new IRI manager class +// +namespace LibIri { +struct Wrapper +{ + Wrapper(const char* aIri); + ~Wrapper(); + iri_t *m_Iri; + //! \brief Returns true if iri is valid + bool Validate(); +}; + +std::ostream & operator<<(std::ostream& a_stream, + const Wrapper& a_wrapper); +} //namespace LibIri + +#endif // _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_LIBIRIWRAPPER_H_ + diff --git a/src/configuration_parser/parser_runner.cpp b/src/configuration_parser/parser_runner.cpp new file mode 100644 index 0000000..79d5f16 --- /dev/null +++ b/src/configuration_parser/parser_runner.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file parser_runner.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#include "parser_runner.h" +#include "root_parser.h" + +#include <stack> +#include <libxml/xmlreader.h> +#include <dpl/binary_queue.h> +#include <dpl/assert.h> +#include <dpl/file_input.h> +#include <dpl/log/log.h> + +class ParserRunner::Impl +{ + public: + void Parse(const std::string& filename, + const ElementParserPtr& root) + { + DPL::FileInput input(filename); + Parse(&input, root); + } + + void Parse (DPL::AbstractInput *input, + const ElementParserPtr& root) + { + Try + { + m_reader = xmlReaderForIO(&IoRead, + &IoClose, + input, + NULL, + NULL, + XML_PARSE_NOENT); + + xmlTextReaderSetErrorHandler(m_reader, + &xmlTextReaderErrorHandler, + this); + xmlTextReaderSetStructuredErrorHandler( + m_reader, + &xmlTextReaderStructuredErrorHandler, + this); + SetCurrentElementParser(root); + + while (xmlTextReaderRead(m_reader) == 1) { + switch (xmlTextReaderNodeType(m_reader)) { + case XML_READER_TYPE_END_ELEMENT: + VerifyAndRemoveCurrentElementParser(); + break; + + case XML_READER_TYPE_ELEMENT: + { + // Elements without closing tag don't receive + // XML_READER_TYPE_END_ELEMENT event. + if (IsNoClosingTagElementLeft()) { + VerifyAndRemoveCurrentElementParser(); + } + + DPL::String elementName = GetNameWithoutNamespace(); + DPL::String nameSpace = GetNamespace(); + ElementParserPtr parser = GetCurrentElementParser(); + parser = parser->GetElementParser(nameSpace, + elementName) (); + Assert(!!parser); + SetCurrentElementParser(parser); + ParseNodeElement(parser); + break; + } + case XML_READER_TYPE_TEXT: + case XML_READER_TYPE_CDATA: + { + ParseNodeText(GetCurrentElementParser()); + break; + } + default: + LogWarning("Ignoring Node of Type: " << + xmlTextReaderNodeType(m_reader)); + break; + } + + if (m_parsingError) { + LogError("Parsing error occured: " << m_errorMsg); + ThrowMsg(ElementParser::Exception::ParseError, m_errorMsg); + } + } + + if (m_parsingError) { + LogError("Parsing error occured: " << m_errorMsg); + ThrowMsg(ElementParser::Exception::ParseError, m_errorMsg); + } + + while (!m_stack.empty()) { + VerifyAndRemoveCurrentElementParser(); + } + } + Catch(ElementParser::Exception::Base) + { + CleanupParserRunner(); + LogError(_rethrown_exception.DumpToString()); + ReThrow(ElementParser::Exception::ParseError); + } + CleanupParserRunner(); + } + + Impl() : + m_reader(NULL), + m_parsingError(false) + { + } + + ~Impl() + { + CleanupParserRunner(); + } + + private: + typedef std::stack<ElementParserPtr> ElementStack; + + private: + static void xmlTextReaderErrorHandler(void* arg, + const char* msg, + xmlParserSeverities /* severity */, + xmlTextReaderLocatorPtr /* locator */) + { + ParserRunner::Impl* impl = static_cast<ParserRunner::Impl*>(arg); + impl->ErrorHandler(DPL::FromASCIIString(msg)); + } + + static void xmlTextReaderStructuredErrorHandler(void* arg, + xmlErrorPtr error) + { + ParserRunner::Impl* impl = static_cast<ParserRunner::Impl*>(arg); + impl->StructuredErrorHandler(error); + } + + static int XMLCALL IoRead(void *context, + char *buffer, + int len) + { + DPL::AbstractInput *input = static_cast<DPL::AbstractInput *>(context); + DPL::BinaryQueueAutoPtr data = input->Read(static_cast<size_t>(len)); + if (!data.get()) { + return -1; + } + data->Flatten(buffer, data->Size()); + return static_cast<int>(data->Size()); + } + + static int XMLCALL IoClose(void */* context */) + { + // NOOP + return 0; + } + + private: + void SetCurrentElementParser(const ElementParserPtr& elementParser) + { + Assert(elementParser); + + m_stack.push(elementParser); + } + + const ElementParserPtr& GetCurrentElementParser() const + { + Assert(!m_stack.empty()); + + return m_stack.top(); + } + + void VerifyAndRemoveCurrentElementParser() + { + Assert(!m_stack.empty()); + + m_stack.top()->Verify(); + m_stack.pop(); + } + + bool IsNoClosingTagElementLeft() const + { + Assert(m_reader); + + int depth = xmlTextReaderDepth(m_reader); + return (static_cast<int>(m_stack.size()) - 2 == depth); + } + + void ParseNodeElement(const ElementParserPtr& parser) + { + Assert(m_reader); + + Element element; + element.name = GetNameWithoutNamespace(); + element.value = GetValue(); + element.lang = GetLanguageTag(); + element.ns = GetNamespace(); + + LogDebug("value: " << element.value << + ", lang: " << element.lang << + ", ns: " << element.ns << ")"); + + parser->Accept(element); + ParseNodeElementAttributes(parser); + } + + void ParseNodeElementAttributes(const ElementParserPtr& parser) + { + Assert(m_reader); + + int count = xmlTextReaderAttributeCount(m_reader); + for (int i = 0; i < count; ++i) { + xmlTextReaderMoveToAttributeNo(m_reader, i); + + XmlAttribute attribute; + attribute.name = GetName(); + attribute.value = GetValue(); + attribute.lang = GetLanguageTag(); + LogDebug("Attribute name: " << attribute.name << + ", value: " << attribute.value << + ", lang: " << attribute.lang); + parser->Accept(attribute); + } + } + + void ParseNodeText(const ElementParserPtr& parser) + { + Text text; + text.value = GetValue(); + text.lang = GetLanguageTag(); + parser->Accept(text); + } + + DPL::String GetValue() const + { + DPL::String ret_value; + const xmlChar* value = xmlTextReaderConstValue(m_reader); + if (value) { + ret_value = DPL::FromUTF8String(reinterpret_cast<const char*>(value)); + } + + return ret_value; + } + + DPL::String GetAttributeValue(int pos) const + { + DPL::String ret_value; + const xmlChar* value = xmlTextReaderGetAttributeNo(m_reader, pos); + if (value) { + ret_value = DPL::FromUTF8String(reinterpret_cast<const char*>(value)); + } + xmlFree(const_cast<xmlChar*>(value)); + + return ret_value; + } + + DPL::String GetName() const + { + DPL::String ret_value; + const xmlChar* value = xmlTextReaderConstName(m_reader); + if (value) { + ret_value = DPL::FromUTF8String(reinterpret_cast<const char*>(value)); + } + + return ret_value; + } + + DPL::String GetNameWithoutNamespace() const + { + DPL::String ret_value; + const xmlChar* value = xmlTextReaderLocalName(m_reader); + if (value) { + ret_value = DPL::FromUTF8String(reinterpret_cast<const char*>(value)); + } + + return ret_value; + } + + DPL::String GetNamespace() const + { + DPL::String ret_value; + const xmlChar* value = xmlTextReaderConstNamespaceUri(m_reader); + if (value) { + ret_value = DPL::FromUTF8String(reinterpret_cast<const char*>(value)); + } + + return ret_value; + } + + DPL::String GetLanguageTag() const + { + DPL::String ret_value; + const xmlChar* value = xmlTextReaderConstXmlLang(m_reader); + if (value) { + ret_value = DPL::FromUTF8String(reinterpret_cast<const char*>(value)); + } + + return ret_value; + } + + void ErrorHandler(const DPL::String& msg) + { + LogError("LibXML: " << msg); + m_parsingError = true; + m_errorMsg = m_errorMsg + DPL::FromASCIIString("\n"); + m_errorMsg = m_errorMsg + msg; + } + + void StructuredErrorHandler(xmlErrorPtr error) + { + LogError("LibXML: " << error->message); + m_parsingError = true; + m_errorMsg = m_errorMsg + DPL::FromASCIIString("\n"); + m_errorMsg = m_errorMsg + DPL::FromUTF8String(error->message); + } + + void CleanupParserRunner() + { + while (!m_stack.empty()) { + m_stack.pop(); + } + if (m_reader) { + xmlFreeTextReader(m_reader); + } + m_reader = NULL; + } + + private: + xmlTextReaderPtr m_reader; + ElementStack m_stack; + bool m_parsingError; + DPL::String m_errorMsg; +}; + +ParserRunner::ParserRunner() : + m_impl(new ParserRunner::Impl()) +{ +} + +void ParserRunner::Parse(const std::string& filename, + ElementParserPtr root) +{ + m_impl->Parse(filename, root); +} + +void ParserRunner::Parse(DPL::AbstractInput *input, + ElementParserPtr root) +{ + m_impl->Parse(input, root); +} + +ParserRunner::~ParserRunner() +{ + delete m_impl; +} diff --git a/src/configuration_parser/parser_runner.h b/src/configuration_parser/parser_runner.h new file mode 100644 index 0000000..1176165 --- /dev/null +++ b/src/configuration_parser/parser_runner.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file parser_runner.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef PARSER_RUNNER_H_ +#define PARSER_RUNNER_H_ + +#include <string> +#include <dpl/noncopyable.h> +#include <dpl/abstract_input.h> +#include "element_parser.h" + +class ParserRunner : private DPL::Noncopyable +{ + public: + void Parse(const std::string& filename, + ElementParserPtr root); + void Parse(DPL::AbstractInput *input, + ElementParserPtr root); + + ParserRunner(); + ~ParserRunner(); + + private: + class Impl; + Impl* m_impl; +}; + +#endif // PARSER_RUNNER_H_ + diff --git a/src/configuration_parser/powder_parser.cpp b/src/configuration_parser/powder_parser.cpp new file mode 100644 index 0000000..cb9de64 --- /dev/null +++ b/src/configuration_parser/powder_parser.cpp @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file powder_parser.cpp + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 0.1 + * @brief Parser for WAC defined POWDER + */ + +#include <algorithm> +#include <cstdio> +#include <cerrno> +#include <ewk_main.h> +#include <dpl/log/log.h> +#include <dpl/sstream.h> +#include <dpl/foreach.h> +#include "powder_parser.h" +#include "ignoring_parser.h" +#include "deny_all_parser.h" + +namespace { +void MergeDescriptions(WrtDB::Powder::Description* dest, + const WrtDB::Powder::Description& src) +{ + Assert(dest); +// LogInfo("MergeDescriptions dest: " << *dest << +// " src: " << src); + if (!dest->ageRating) { + dest->ageRating = src.ageRating; + } else { + if (!!src.ageRating) { + if (*dest->ageRating > *src.ageRating) { + dest->ageRating = src.ageRating; + } + } + } + FOREACH(catIter, src.categories) + { + FOREACH(levelIter, catIter->second.levels) + { + dest->categories[catIter->first].levels.push_back(*levelIter); + } + } +// LogInfo("MergeDescriptions result:" << *dest); +} + +//TODO::Check if list of delimiters is valid +const DPL::String constPowderDelimiters = DPL::FromUTF32String(L" ,;\n\r\t"); +} //anonymous namespace + +std::ostream & operator<<(std::ostream& aStream, + const StringSet& aContainer) +{ + if (!aContainer.empty()) { + StringSet::const_iterator iter = aContainer.begin(); + aStream << "{[" << *iter; + ++iter; + for (/*empty*/; iter != aContainer.end(); ++iter) { + aStream << "] [" << *iter; + } + aStream << "]}"; + } + return aStream; +} + +#define DEFINE_ELEMENT_FUNC(element, myClass) \ + m_map[DPL::FromUTF32String(L"" # element)] = \ + DPL::MakeDelegate(this, &myClass::OnElement_ ## element); + +class DenyUnknownTagsParser : public ElementParser +{ + public: + DenyUnknownTagsParser() : ElementParser() + { + } + + void Accept(const XmlAttribute& /*attribute*/) + { + } + + void Accept(const Element& /*element*/) + { + } + + void Accept(const Text& /*text*/) + { + } + + ElementParserPtr OnDenyElement() + { + return ElementParserPtr(new DenyAllParser()); + } + + ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &DenyUnknownTagsParser::OnDenyElement); + } + + protected: + FuncMap m_map; +}; + +StringSet TokenizeTag(const DPL::String& buffer) +{ + StringSet data; + DPL::Tokenize(buffer, constPowderDelimiters, + std::insert_iterator<StringSet>(data, data.begin()), true); + return data; +} + +class SetOfTextValuesParser : public DenyUnknownTagsParser +{ + public: + explicit SetOfTextValuesParser(std::set<DPL::String>* data) : + DenyUnknownTagsParser(), + m_data(data) + { + Assert(m_data); + } + + virtual void Accept(const Text& text) + { + LogDebug("text"); + m_buffer += text.value; + } + void Verify() + { + *m_data = TokenizeTag(m_buffer); + } + + private: + DPL::String m_buffer; + StringSet* m_data; +}; + +// It is data structure used by iriset parser to match IRI's +// and preserve processing result +struct IrisetParserData +{ + const DPL::String* m_host; + const DPL::String* m_path; + bool m_matched; + IrisetParserData(const DPL::String& host, + const DPL::String& path) : + m_host(&host), + m_path(&path), + m_matched(false) + { + } +}; + +class IrisetParser : public DenyUnknownTagsParser +{ + public: + explicit IrisetParser(IrisetParserData* data) : + DenyUnknownTagsParser(), + m_data(data), + m_hostsDetected(0), + m_pathsDetected(0) + { + Assert(m_data); + DEFINE_ELEMENT_FUNC(includehosts, IrisetParser); + DEFINE_ELEMENT_FUNC(includeexactpaths, IrisetParser); + } + + ElementParserPtr OnElement_includehosts() + { + m_hostsDetected++; + return ElementParserPtr(new SetOfTextValuesParser(&m_hosts)); + } + + ElementParserPtr OnElement_includeexactpaths() + { + m_pathsDetected++; + return ElementParserPtr(new SetOfTextValuesParser(&m_paths)); + } + + void Verify() + { + if (m_hostsDetected <= 1 && m_pathsDetected <= 1) { + LogInfo("Matching iriset for host [" << + *m_data->m_host << "] path [" << + *m_data->m_path << "]"); + LogInfo("hosts: " << m_hosts << + " paths: " << m_paths); + m_data->m_matched = + m_hosts.find(*m_data->m_host) != m_hosts.end() && + m_paths.find(*m_data->m_path) != m_paths.end(); + } else { + ThrowMsg(PowderParserException::ParserFailed, + "Invalid iriset contents"); + } + } + + private: + IrisetParserData* m_data; + typedef StringSet Container; + Container m_hosts; + Container m_paths; + size_t m_hostsDetected; + size_t m_pathsDetected; +}; + +class WacCategoryParser : public DenyUnknownTagsParser +{ + public: + WacCategoryParser(WrtDB::Powder::Description::LevelEntry* data) : + DenyUnknownTagsParser(), + m_data(data) + { + Assert(m_data); + } + + virtual void Accept(const Text& text) + { + LogDebug("text"); + m_buffer += text.value; + } + + static StringSet GetAllowedAttributes() + { + StringSet allowed; + allowed.insert(DPL::FromUTF32String(L"xa")); + allowed.insert(DPL::FromUTF32String(L"xb")); + allowed.insert(DPL::FromUTF32String(L"xc")); + allowed.insert(DPL::FromUTF32String(L"xd")); + allowed.insert(DPL::FromUTF32String(L"xe")); + return allowed; + } + + virtual void Accept(const XmlAttribute& attribute) + { + static StringSet allowed = GetAllowedAttributes(); + if (allowed.find(attribute.name) != allowed.end()) { + if (DPL::FromUTF32String(L"1") == attribute.value) { + m_data->context.insert(attribute.name); + } else if (DPL::FromUTF32String(L"0") != attribute.value) { + ThrowMsg(PowderParserException::ParserFailed, + "Invalid attribute for WAC category tag"); + } + } else { + ThrowMsg(PowderParserException::ParserFailed, + "Invalid tag in descriptionset"); + } + } + + virtual void Verify() + { + StringSet values = TokenizeTag(m_buffer); + bool numberFound = false; + + FOREACH(wordIter, values) { + DPL::IStringStream str(*wordIter); + int rating; + str >> rating; + if (str.fail()) { + ThrowMsg(PowderParserException::ParserFailed, + "WAC category level is not number"); + } else { + if (numberFound) { + ThrowMsg(PowderParserException::ParserFailed, + "Too many WAC category levels"); + } else { + if (rating >= MIN_AGE_RATING && rating <= MAX_AGE_RATING) { + m_data->level = + static_cast<WrtDB::Powder::Description::LevelEnum>( + rating); + numberFound = true; + } else { + ThrowMsg(PowderParserException::ParserFailed, + "WAC category level is out of range "); + } + } + } + } + if (!numberFound) { + ThrowMsg(PowderParserException::ParserFailed, + "WAC category level is not present in tag"); + } + } + + private: + WrtDB::Powder::Description::LevelEntry* m_data; + DPL::String m_buffer; + static const int MIN_AGE_RATING = 0; + static const int MAX_AGE_RATING = 5; +}; + +class DescriptorSetParser : public DenyUnknownTagsParser +{ + public: + typedef WrtDB::Powder::Description::CategoryEntries::iterator CatIter; + explicit DescriptorSetParser(WrtDB::Powder::Description* data) : + DenyUnknownTagsParser(), + m_data(data) + { + Assert(m_data); +#define ELEM(tag) DEFINE_ELEMENT_FUNC(tag, DescriptorSetParser) + ELEM(aa); + ELEM(nu); + ELEM(se); + ELEM(vi); + ELEM(la); + ELEM(dr); + ELEM(ga); + ELEM(ha); + ELEM(ug); +#undef ELEM + m_map[DPL::FromUTF32String(L"displayicon")] = + DPL::MakeDelegate(this, &DescriptorSetParser::OnIgnoredElement); + } + + ElementParserPtr OnElement_aa() + { + m_ages.push_back(StringSet()); + return ElementParserPtr(new SetOfTextValuesParser(&m_ages.back())); + } + +#define GENERATE_ELEMENT_FUNC(element) \ + ElementParserPtr OnElement_ ## element() \ + { \ + LogInfo("WAC category tag detected: " << # element); \ + CatIter category = \ + m_data->categories.find(DPL::FromUTF32String(L"" # element)); \ + if (m_data->categories.end() == category) \ + { \ + std::pair<CatIter, bool> result = \ + m_data->categories.insert(std::make_pair( \ + DPL::FromUTF32String(L"" # \ + element), \ + WrtDB::Powder::Description:: \ + CategoryEntry())); \ + category = result.first; \ + } \ + category->second.levels.push_back( \ + WrtDB::Powder::Description::LevelEntry()); \ + return ElementParserPtr(new \ + WacCategoryParser( \ + &category->second.levels.back())); \ + } \ + + GENERATE_ELEMENT_FUNC(nu) + GENERATE_ELEMENT_FUNC(se) + GENERATE_ELEMENT_FUNC(vi) + GENERATE_ELEMENT_FUNC(la) + GENERATE_ELEMENT_FUNC(dr) + GENERATE_ELEMENT_FUNC(ga) + GENERATE_ELEMENT_FUNC(ha) + GENERATE_ELEMENT_FUNC(ug) + +#undef GENERATE_ELEMENT_FUNC + + ElementParserPtr OnIgnoredElement() + { + return ElementParserPtr(new IgnoringParser()); + } + + void Verify() + { + if (m_ages.size() > 1) { + ThrowMsg(PowderParserException::ParserFailed, + "More than one aa tags: not implemented"); + } else if (m_ages.size() == 1) { + if (!m_ages.at(0).empty() && m_ages.at(0).size() <= 1) { + DPL::IStringStream str(*m_ages.at(0).begin()); + int rating = 12; + str >> rating; + if (str.fail()) { + ThrowMsg(PowderParserException::ParserFailed, + "Invalid number in age rating"); + } else { + m_data->ageRating = rating; + } + } else { + ThrowMsg(PowderParserException::ParserFailed, + "Not valid age value in aa tag "); + } + } +// LogInfo("Descriptionset verified: " << *m_data); + } + + private: + typedef std::vector<StringSet> AgesTags; + AgesTags m_ages; + WrtDB::Powder::Description* m_data; +}; + +class DrParser : public DenyUnknownTagsParser +{ + public: + DrParser(WrtDB::Powder::Description* data, + const DPL::String& host, + const DPL::String& path) : + DenyUnknownTagsParser(), + m_data(data), + m_host(host), + m_path(path) + { + Assert(m_data); + DEFINE_ELEMENT_FUNC(iriset, DrParser); + DEFINE_ELEMENT_FUNC(descriptorset, DrParser); + } + + ElementParserPtr OnElement_iriset() + { + m_iriSetOutcomes.push_back(IrisetParserData(m_host, m_path)); + return ElementParserPtr(new IrisetParser(&m_iriSetOutcomes.back())); + } + + ElementParserPtr OnElement_descriptorset() + { + m_descriptions.push_back(WrtDB::Powder::Description()); + return ElementParserPtr(new + DescriptorSetParser(&m_descriptions.back())); + } + + void Verify() + { + if (m_iriSetOutcomes.empty() || m_descriptions.empty()) { + ThrowMsg( + PowderParserException::ParserFailed, + "dr tag don't contain at lease one iriset and descriptionset "); + } else { + IriSetOutcomes::const_iterator outIter; + for (outIter = m_iriSetOutcomes.begin(); + outIter != m_iriSetOutcomes.end() && !outIter->m_matched; + ++outIter) { + } + if (outIter != m_iriSetOutcomes.end()) { + LogInfo("Matching iriset found"); + typedef PowderDescriptions::const_iterator DescIter; + for (DescIter descIter = m_descriptions.begin(); + descIter != m_descriptions.end(); ++descIter) { + MergeDescriptions(m_data, *descIter); + } + } else { + LogWarning("No matching iriset found"); + } + } +// LogInfo("dr tag verified" << *m_data); + } + private: + typedef std::vector<WrtDB::Powder::Description> PowderDescriptions; + PowderDescriptions m_descriptions; + typedef std::vector<IrisetParserData> IriSetOutcomes; + IriSetOutcomes m_iriSetOutcomes; + WrtDB::Powder::Description* m_data; + const DPL::String& m_host; + const DPL::String& m_path; +}; + +PowderParser::PowderParser(PowderParserData* data) : + ElementParser(), + m_data(data->description), + m_host(data->host), + m_path(data->path) +{ + Assert(m_data); + m_map[DPL::FromUTF32String(L"attribution")] = + DPL::MakeDelegate(this, &PowderParser::OnIgnoredElement); + DEFINE_ELEMENT_FUNC(dr, PowderParser); +} + +ElementParserPtr PowderParser::OnIgnoredElement() +{ + return ElementParserPtr(new IgnoringParser()); +} + +ElementParserPtr PowderParser::OnElement_dr() +{ + return ElementParserPtr(new DrParser(m_data, m_host, m_path)); +} + +void PowderParser::Accept(const Element& /*element*/) +{ +} + +void PowderParser::Accept(const XmlAttribute& /*attribute*/) +{ +} + +void PowderParser::Accept(const Text& /*text*/) +{ +} + +void PowderParser::Verify() +{ +// LogInfo("powder tag verified " << *m_data); +} + +ElementParserPtr PowderParser::OnDenyElement() +{ + return ElementParserPtr(new DenyAllParser()); +} + +ElementParser::ActionFunc PowderParser::GetElementParser(const DPL::String& /*ns*/, + const DPL::String& name) +{ + FuncMap::const_iterator it = m_map.find(name); + if (it != m_map.end()) { + return it->second; + } else { + return DPL::MakeDelegate(this, &PowderParser::OnDenyElement); + } +} + +#undef DEFINE_ELEMENT_FUNC diff --git a/src/configuration_parser/powder_parser.h b/src/configuration_parser/powder_parser.h new file mode 100644 index 0000000..b56ee5b --- /dev/null +++ b/src/configuration_parser/powder_parser.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file powder_parser.h + * @author Piotr Marcinkiewicz (p.marcinkiew@samsung.com) + * @version 0.1 + * @brief Parser for WAC defined POWDER + */ + +#ifndef _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_POWDER_PARSER_H_ +#define _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_POWDER_PARSER_H_ + +#include <dpl/exception.h> +#include "element_parser.h" +#include <dpl/wrt-dao-ro/common_dao_types.h> + +//TODO: Move to separate header +namespace PowderParserException { +DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) +DECLARE_EXCEPTION_TYPE(Base, ParserFailed) +} + +struct PowderParserData +{ + WrtDB::Powder::Description* description; + const DPL::String& host; + const DPL::String& path; + PowderParserData(WrtDB::Powder::Description* a_description, + const DPL::String& a_host, + const DPL::String& a_path) : + description(a_description), + host(a_host), + path(a_path) + { + } +}; +//TODO: Move to other header +typedef std::set<DPL::String> StringSet; + +class PowderParser : public ElementParser +{ + public: + //Typedef used by RootParser + typedef PowderParserData* Data; + + explicit PowderParser(PowderParserData* data); + + ElementParserPtr OnNameElement(); + + //TODO: Remove not implemented methods + virtual ActionFunc GetElementParser(const DPL::String& ns, + const DPL::String& name); + virtual void Accept(const Element& /*element*/); + virtual void Accept(const XmlAttribute& attribute); + virtual void Accept(const Text& text); + virtual void Verify(); + + ElementParserPtr OnIgnoredElement(); + ElementParserPtr OnElement_dr(); + ElementParserPtr OnDenyElement(); + + private: + WrtDB::Powder::Description* m_data; + const DPL::String& m_host; + const DPL::String& m_path; + FuncMap m_map; +}; +#endif // _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_POWDER_PARSER_H_ diff --git a/src/configuration_parser/root_parser.h b/src/configuration_parser/root_parser.h new file mode 100644 index 0000000..3f4a86b --- /dev/null +++ b/src/configuration_parser/root_parser.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file root_parser.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_ROOT_PARSER_H_ +#define _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_ROOT_PARSER_H_ + +#include <dpl/log/log.h> +#include "element_parser.h" + +template<typename ta_Parser> +class RootParser : public ElementParser +{ + public: + typedef typename ta_Parser::Data Data; + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& name) + { + if (name == m_tag) { + return DPL::MakeDelegate(this, + &RootParser<ta_Parser>::OnWidgetElement); + } else { + ThrowMsg(Exception::ParseError, + name << " != " << m_tag); + } + } + + RootParser(Data data, + const DPL::String& tag) : + m_data(data), + m_tag(tag) + { + } + + virtual ~RootParser() + { + } + + virtual void Accept(const Element& /*element*/) + { + LogDebug("element"); + } + + virtual void Accept(const XmlAttribute& /*attribute*/) + { + LogDebug("attribute"); + } + + virtual void Accept(const Text& /*text*/) + { + LogDebug("text"); + } + + virtual void Verify() + { + LogDebug(""); + } + + private: + + ElementParserPtr OnWidgetElement() + { + typedef ta_Parser Parser; + return ElementParserPtr(new Parser(this->m_data)); + } + + Data m_data; + const DPL::String& m_tag; +}; + +#endif // _WRT_ENGINE_SRC_INSTALLERCORE_CONFIGURATION_PARSER_ROOT_PARSER_H_ diff --git a/src/configuration_parser/widget_parser.cpp b/src/configuration_parser/widget_parser.cpp new file mode 100644 index 0000000..e46b2a7 --- /dev/null +++ b/src/configuration_parser/widget_parser.cpp @@ -0,0 +1,1662 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + /** + * This file have been implemented in compliance with W3C WARP SPEC. + * but there are some patent issue between W3C WARP SPEC and APPLE. + * so if you want to use this file, refer to the README file in root directory + */ +/** + * @file widget_parser.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#include "widget_parser.h" +#include "ignoring_parser.h" +#include "deny_all_parser.h" +#include <dpl/wrt-dao-ro/config_parser_data.h> +#include "libiriwrapper.h" +#include <dpl/utils/warp_iri.h> +#include <dpl/utils/mime_type_utils.h> +#include <language_subtag_rst_tree.h> +#include <ewk_main.h> + +#include <iri.h> +#include <dpl/log/log.h> +#include <dpl/fast_delegate.h> +#include <dpl/foreach.h> +#include <algorithm> +#include <cstdio> +#include <cerrno> + +using namespace WrtDB; + +namespace Unicode { +static const DPL::String UTF_LRE = L"\x0202a"; +static const DPL::String UTF_LRO = L"\x0202d"; +static const DPL::String UTF_RLE = L"\x0202b"; +static const DPL::String UTF_RLO = L"\x0202e"; +static const DPL::String UTF_PDF = L"\x0202c"; + +Direction ParseDirAttribute(const XmlAttribute& attribute) +{ + Assert(L"dir" == attribute.name); + if (L"ltr" == attribute.value) { + return LRE; + } else if (L"rtl" == attribute.value) { + return RLE; + } else if (L"lro" == attribute.value) { + return LRO; + } else if (L"rlo" == attribute.value) { + return RLO; + } else { + LogWarning("dir attribute has wrong value:" << attribute.value); + return EMPTY; + } +} + +void UpdateTextWithDirectionMark(Direction direction, + DPL::String* text) +{ + Assert(text); + switch (direction) { + case RLO: + *text = UTF_RLO + *text + UTF_PDF; + break; + case RLE: + *text = UTF_RLE + *text + UTF_PDF; + break; + case LRE: + *text = UTF_LRE + *text + UTF_PDF; + break; + case LRO: + *text = UTF_LRO + *text + UTF_PDF; + break; + case EMPTY: + break; + default: + Assert(false); + } +} +} // namespace Unicode + +class InnerElementsParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &InnerElementsParser::Other); + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const Text& text) + { + if (m_text.IsNull()) { + m_text = text; + } else { + m_text->value += text.value; + } + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"dir") { + m_textDirection = Unicode::ParseDirAttribute(attribute); + } + } + + virtual void Verify() + { + if (!m_text.IsNull()) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, + &m_text->value); + m_parentParser->Accept(*m_text); + } + } + + InnerElementsParser(ElementParserPtr parent) : + m_parentParser(parent), + m_textDirection(Unicode::EMPTY) + { + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + DPL::StaticPointerCast<ElementParser>( + SharedFromThis()))); + } + + private: + DPL::Optional<Text> m_text; + ElementParserPtr m_parentParser; + Unicode::Direction m_textDirection; +}; + +class NameParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &NameParser::Other); + } + + virtual void Accept(const Element& element) + { + m_lang = element.lang; + m_name = L""; + } + + virtual void Accept(const Text& text) + { + if (m_name.IsNull()) { + m_name = text.value; + } else { + *m_name += text.value; + } + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"short") { + if (m_shortName.IsNull()) { + m_shortName = attribute.value; + } + } else if (attribute.name == L"dir") { + m_textDirection = Unicode::ParseDirAttribute(attribute); + } + } + + virtual void Verify() + { + ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang]; + if (data.name.IsNull()) { + NormalizeString(m_name); + NormalizeString(m_shortName); + if (!m_name.IsNull()) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name); + } + data.name = m_name; + if (!m_shortName.IsNull()) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, + &*m_shortName); + } + data.shortName = m_shortName; + } + } + + NameParser(Unicode::Direction direction, + ConfigParserData& data) : + m_data(data), + m_textDirection(direction) + { + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + DPL::StaticPointerCast<ElementParser>( + SharedFromThis()))); + } + + private: + ConfigParserData& m_data; + DPL::OptionalString m_name; + DPL::OptionalString m_shortName; + DPL::OptionalString m_dir; + DPL::String m_lang; + Unicode::Direction m_textDirection; +}; + +class AccessParser : public ElementParser +{ + public: + enum StandardType + { + STANDARD_TYPE_NONE, + STANDARD_TYPE_JIL, + STANDARD_TYPE_WARP + }; + + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &AccessParser::Other); + } + + virtual void Accept(const Element& element) + { + if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) { + m_standardType = STANDARD_TYPE_WARP; + } + if (element.ns == ConfigurationNamespace::JilWidgetNamespaceName) { + m_standardType = STANDARD_TYPE_JIL; + } + } + + virtual void Accept(const Text& /*text*/) + { + } + + void AcceptWac(const XmlAttribute& attribute) + { + if (attribute.name == L"origin") { + m_strIRIOrigin = attribute.value; + NormalizeString(m_strIRIOrigin); + } else if (attribute.name == L"subdomains") { + DPL::String normalizedValue = attribute.value; + NormalizeString(normalizedValue); + + if (normalizedValue == L"true") { + m_bSubDomainAccess = true; + } else if (normalizedValue == L"false") { + m_bSubDomainAccess = false; + } + } + } + + void AcceptJil(const XmlAttribute& attribute) + { + if (attribute.name == DPL::FromASCIIString("network")) { + if (attribute.value == DPL::FromASCIIString("true")) { + m_network = true; + } else { + m_network = false; + } + } + } + + virtual void Accept(const XmlAttribute& attribute) + { + switch (m_standardType) { + case STANDARD_TYPE_WARP: + AcceptWac(attribute); + break; + case STANDARD_TYPE_JIL: + AcceptJil(attribute); + break; + default: + LogError("Error in Access tag - unknown standard."); + } + } + + void VerifyWac() + { + WarpIRI iri; + iri.set(m_strIRIOrigin, false); + + if (!iri.isAccessDefinition()) { + LogWarning("Access list element: " << + m_strIRIOrigin << + " is not acceptable by WARP" << + "standard and will be ignored!"); + return; + } + + ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin, + m_bSubDomainAccess); + std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret = + m_data.accessInfoSet.insert(accessInfo); + } + + void VerifyJil() + { + m_data.accessNetwork = m_network; + } + + virtual void Verify() + { + switch (m_standardType) { + case STANDARD_TYPE_WARP: + VerifyWac(); + break; + case STANDARD_TYPE_JIL: + VerifyJil(); + break; + default: + LogError("Error in Access tag - unknown standard."); + } + } + + AccessParser(ConfigParserData& data) : + ElementParser(), + m_bSubDomainAccess(false), + m_standardType(STANDARD_TYPE_NONE), + m_network(false), + m_data(data) + { + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + ElementParserPtr(SharedFromThis()))); + } + + private: + DPL::String m_strIRIOrigin; + bool m_bSubDomainAccess; + StandardType m_standardType; + bool m_network; + ConfigParserData& m_data; +}; + +class PkgnameParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &DenyAllParser::Create; + } + + virtual void Accept(const Element& element) + { + if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) { + m_properNamespace = true; + } + + LogDebug("element pkgname"); + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + DPL::StaticPointerCast<ElementParser>( + SharedFromThis()))); + } + + virtual void Accept(const Text& text) + { + if(m_properNamespace) { + m_pkgname = text.value; + LogDebug("Pkgname value: " << m_pkgname); + } + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (m_properNamespace) { + ThrowMsg(Exception::ParseError, + "attirubte: '" + DPL::ToUTF8String(attribute.name) + + "' in pkgname element not allowed"); + } + } + + virtual void Verify() + { + if (m_properNamespace) { + if (m_pkgname.IsNull()) { + ThrowMsg(Exception::ParseError, + "pkgname element must have value"); + } + m_data.pkgname = m_pkgname; + LogDebug("Pkgname = " << m_pkgname); + } + } + + PkgnameParser(ConfigParserData& data) : + m_properNamespace(false), + m_data(data), + m_pkgname() + { + } + + private: + bool m_properNamespace; + ConfigParserData& m_data; + DPL::OptionalString m_pkgname; +}; + +class DescriptionParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &DescriptionParser::Other); + } + + virtual void Accept(const Element& element) + { + m_lang = element.lang; + m_description = L""; + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + DPL::StaticPointerCast<ElementParser>( + SharedFromThis()))); + } + + virtual void Accept(const Text& text) + { + if (m_description.IsNull()) { + m_description = text.value; + } else { + *m_description += text.value; + } + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"dir") { + m_textDirection = Unicode::ParseDirAttribute(attribute); + } + } + + virtual void Verify() + { + ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang]; + if (data.description.IsNull()) { + if (!m_description.IsNull()) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, + &*m_description); + } + data.description = m_description; + } + } + + DescriptionParser(Unicode::Direction direction, + ConfigParserData& data) : + m_data(data), + m_lang(), + m_description(), + m_textDirection(direction) + { + } + + private: + ConfigParserData& m_data; + DPL::String m_lang; + DPL::OptionalString m_description; + Unicode::Direction m_textDirection; +}; + +class AuthorParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &AuthorParser::Other); + } + + AuthorParser(Unicode::Direction direction, + ConfigParserData& data) : + m_data(data), + m_textDirection(direction) + { + } + + virtual void Accept(const Element& /*element*/) + { + m_authorName = L""; + } + + virtual void Accept(const Text& text) + { + *(m_authorName) += text.value; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"href") { + //Validate href IRI and ignore it if invalid + //See also test: ta-argMozRiC-an + LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str()); + if (iri.Validate()) { + m_authorHref = attribute.value; + } + } else if (attribute.name == L"email") { + m_authorEmail = attribute.value; + } else if (attribute.name == L"dir") { + m_textDirection = Unicode::ParseDirAttribute(attribute); + } + } + + virtual void Verify() + { + if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) { + NormalizeString(m_authorName); + NormalizeString(m_authorHref); + NormalizeString(m_authorEmail); + if (!!m_authorName) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, + &*m_authorName); + m_data.authorName = m_authorName; + } + if (!!m_authorHref) { + m_data.authorHref = m_authorHref; + } + if (!!m_authorEmail) { + m_data.authorEmail = m_authorEmail; + } + } + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + DPL::StaticPointerCast<ElementParser>( + SharedFromThis()))); + } + + private: + ConfigParserData& m_data; + DPL::OptionalString m_authorEmail; + DPL::OptionalString m_authorHref; + DPL::OptionalString m_authorName; + Unicode::Direction m_textDirection; +}; + +class LicenseParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return DPL::MakeDelegate(this, &LicenseParser::Other); + } + + LicenseParser(Unicode::Direction direction, + ConfigParserData& data) : + m_data(data), + m_ignore(true), + m_textDirection(direction) + { + } + + virtual void Accept(const Element& element) + { + if (m_license.IsNull()) { + m_lang = element.lang; + m_license = L""; + m_ignore = false; + } + } + + virtual void Accept(const Text& text) + { + if (!m_ignore) { + *m_license += text.value; + } + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (!m_ignore) { + if (attribute.name == L"href" && m_licenseHref.IsNull()) { + m_licenseHref = attribute.value; + } else if (attribute.name == L"file" && m_licenseFile.IsNull()) { + m_licenseFile = attribute.value; + } else if (attribute.name == L"dir") { + m_textDirection = Unicode::ParseDirAttribute(attribute); + } + } + } + + virtual void Verify() + { + ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang]; + if (data.license.IsNull()) { + if (!m_license.IsNull()) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, + &*m_license); + } + data.license = m_license; + data.licenseHref = m_licenseHref; + data.licenseFile = m_licenseFile; + } + } + + ElementParserPtr Other() + { + return ElementParserPtr(new InnerElementsParser( + ElementParserPtr(SharedFromThis()))); + } + + private: + ConfigParserData& m_data; + DPL::String m_lang; + bool m_ignore; + + DPL::OptionalString m_license; + DPL::OptionalString m_licenseFile; + DPL::OptionalString m_licenseHref; + Unicode::Direction m_textDirection; +}; + +class IconParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + IconParser(ConfigParserData& data) : ElementParser(), + m_data(data) + { + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"src") { + if (attribute.value.size() > 0) { + m_src = attribute.value; + } + } else if (attribute.name == L"width") { + m_width = ParseSizeAttributeValue(attribute.value); + } else if (attribute.name == L"height") { + m_height = ParseSizeAttributeValue(attribute.value); + } + } + + virtual void Accept(const Text& /*text*/) + { + ThrowMsg(Exception::ParseError, "Icon element must be empty"); + } + + virtual void Verify() + { + if (m_src.IsNull()) { + LogWarning("src attribute of icon element is mandatory - ignoring"); + return; + } + + ConfigParserData::Icon icon(*m_src); + icon.width = m_width; + icon.height = m_height; + + ConfigParserData::IconsList::iterator it = std::find( + m_data.iconsList.begin(), m_data.iconsList.end(), icon); + if (it == m_data.iconsList.end()) { + m_data.iconsList.push_front(icon); + } + } + + private: + ConfigParserData& m_data; + DPL::OptionalString m_src; + DPL::OptionalInt m_width; + DPL::OptionalInt m_height; + + static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value) + { + DPL::OptionalString normalizedValue = value; + NormalizeString(normalizedValue); + if (!(*normalizedValue).empty()) { + char* reterr = NULL; + errno = 0; + long int valueInt = + strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10); + if (errno != 0 || + std::string(reterr) == DPL::ToUTF8String(value) || + valueInt <= 0) { + return DPL::OptionalInt::Null; + } else { + return valueInt; + } + } + return DPL::OptionalInt::Null; + } +}; + +class ContentParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + ContentParser(ConfigParserData& data) : + ElementParser(), + m_data(data) + { + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Accept(const XmlAttribute& attribute) + { + DPL::String value = attribute.value; + NormalizeString(value); + + if (attribute.name == L"src") { + m_src = value; + } else if (attribute.name == L"type") { + m_type = value; + MimeTypeUtils::MimeAttributes mimeAttributes = + MimeTypeUtils::getMimeAttributes(value); + if (mimeAttributes.count(L"charset") > 0) { + m_encoding = mimeAttributes[L"charset"]; + } + } else if (attribute.name == L"encoding") { + if (!value.empty()) { + m_encoding = value; + } + } + } + + virtual void Verify() + { + if (m_data.startFileEncountered) { + LogWarning("This is not the first encountered " + "'content' element - ignoring."); + return; + } + + m_data.startFileEncountered = true; + + //we're consciously setting startFile even if m_src is null or invalid. + //WidgetConfigurationManager will deal with this. + m_data.startFile = m_src; + + if (!!m_src) { + m_data.startFileContentType = m_type; + if (!!m_encoding && ewk_text_encoding_is_valid( + DPL::ToUTF8String(*m_encoding).c_str())) { + m_data.startFileEncoding = m_encoding; + } else { + m_data.startFileEncoding = L"UTF-8"; + } + } + } + + private: + DPL::OptionalString m_src; + DPL::OptionalString m_type; + DPL::OptionalString m_encoding; + ConfigParserData& m_data; +}; + +class FeatureParser : public ElementParser +{ + public: + struct ParamParser : public ElementParser + { + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"name") { + m_name = attribute.value; + NormalizeString(m_name); + } else if (attribute.name == L"value") { + m_value = attribute.value; + NormalizeString(m_value); + } + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const Text& /*text*/) + { + ThrowMsg(Exception::ParseError, "param element must be empty"); + } + + virtual void Verify() + { + if (m_name.IsNull() || *m_name == L"") { + return; + } + if (m_value.IsNull() || *m_value == L"") { + return; + } + + ConfigParserData::Param param(*m_name); + param.value = *m_value; + + if (m_data.paramsList.find(param) == m_data.paramsList.end()) { + m_data.paramsList.insert(param); + } + } + + ParamParser(ConfigParserData::Feature& data) : + ElementParser(), + m_data(data) + { + } + + private: + DPL::OptionalString m_name; + DPL::OptionalString m_value; + ConfigParserData::Feature& m_data; + }; + + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& name) + { + if (name == L"param") { + return DPL::MakeDelegate(this, &FeatureParser::OnParamElement); + } else { + return &IgnoringParser::Create; + } + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"name") { + m_feature.name = attribute.value; + } else if (attribute.name == L"required") { + if (attribute.value == L"false") { + m_feature.required = false; + } else { + m_feature.required = true; + } + } + } + + virtual void Verify() + { + LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str()); + + if (m_feature.name != L"") { + if (iri.Validate()) { + if (m_data.featuresList.find(m_feature) == + m_data.featuresList.end()) { + m_data.featuresList.insert(m_feature); + } else { + LogDebug("Ignoring feature with name" << + DPL::ToUTF8String(m_feature.name)); + } + } else { + if (m_feature.required) { + //Throw only if required + ThrowMsg(Exception::ParseError, "invalid feature IRI"); + } + } + } + } + + ElementParserPtr OnParamElement() + { + return ElementParserPtr(new ParamParser(m_feature)); + } + + FeatureParser(ConfigParserData& data) : + ElementParser(), + m_data(data), + m_feature(L"") + { + } + + private: + ConfigParserData& m_data; + ConfigParserData::Feature m_feature; +}; + +class PreferenceParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"name") { + m_name = attribute.value; + } else if (attribute.name == L"value") { + m_value = attribute.value; + } else if (attribute.name == L"readonly") { + if (attribute.value == L"true") { + m_required = true; + } else { + m_required = false; + } + } + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const Text& /*text*/) + { + ThrowMsg(Exception::ParseError, "param element must be empty"); + } + + virtual void Verify() + { + if (m_name.IsNull()) { + LogWarning("preference element must have name attribute"); + return; + } + NormalizeString(m_name); + NormalizeString(m_value); + ConfigParserData::Preference preference(*m_name, m_required); + preference.value = m_value; + if (m_data.preferencesList.find(preference) == + m_data.preferencesList.end()) { + m_data.preferencesList.insert(preference); + } + } + + PreferenceParser(ConfigParserData& data) : + ElementParser(), + m_required(false), + m_data(data) + { + } + + private: + DPL::OptionalString m_name; + DPL::OptionalString m_value; + bool m_required; + ConfigParserData& m_data; +}; + +class FlashParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"needed") { + if (attribute.value == L"true") { + m_flashNeeded = true; + } else { + m_flashNeeded = false; + } + } + } + + virtual void Accept(const Element& /*element*/) + { + //if empty flash element will be passed, we say true + m_data.flashNeeded = true; + } + + virtual void Accept(const Text& /*text*/) + { + ThrowMsg(Exception::ParseError, "flash element must be empty"); + } + + virtual void Verify() + { + m_data.flashNeeded = m_flashNeeded; + } + + FlashParser(ConfigParserData& data) : + ElementParser(), + m_flashNeeded(false), + m_data(data) + { + } + + private: + bool m_flashNeeded; + ConfigParserData& m_data; +}; + +class LinkParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &DenyAllParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (m_properNamespace) { + LogDebug("attribute"); + if (attribute.name == L"rel") { + if (attribute.value != L"describedby") { + ThrowMsg(Exception::ParseError, + "rel attribute must have describedby value"); + } + } else if (attribute.name == L"type") { + } else if (attribute.name == L"href") { + LogDebug("here is href"); + m_href = attribute.value; + } else { + ThrowMsg(Exception::ParseError, + "unknown attribute '" + + DPL::ToUTF8String(attribute.name) + + "' in link element"); + } + } + } + + virtual void Accept(const Element& element) + { + if (element.ns == + ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement) + { + m_properNamespace = true; + } + LogDebug("element"); + } + + virtual void Accept(const Text&) + { + if (m_properNamespace) { + LogDebug("text"); + ThrowMsg(Exception::ParseError, "link element must be empty"); + } + } + + virtual void Verify() + { + if (!m_href) { + ThrowMsg(Exception::ParseError, + "link element must have href attribute"); + } + + LibIri::Wrapper iri(DPL::ToUTF8String(*m_href).c_str()); + if (!iri.Validate()) { // TODO: Better uri validator ? + ThrowMsg(Exception::ParseError, + "href attribute must be a valid iri/uri/url"); + } + + m_data.powderDescriptionLinks.insert(*m_href); + } + + LinkParser(ConfigParserData& data) : + ElementParser(), + m_properNamespace(false), + m_data(data), + m_href(DPL::OptionalString::Null) + { + } + + private: + bool m_properNamespace; + ConfigParserData& m_data; + DPL::OptionalString m_href; +}; + +class MinVersionParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &DenyAllParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (m_properNamespace) { + ThrowMsg(Exception::ParseError, + "attirubte: '" + DPL::ToUTF8String(attribute.name) + + "' in min-version element not allowed"); + } + } + + virtual void Accept(const Element& element) + { + if (element.ns == ConfigurationNamespace::WacWidgetNamespaceName) { + m_properNamespace = true; + } + + LogDebug("element min-version"); + } + + virtual void Accept(const Text& text) + { + if (m_properNamespace) { + m_minVersion = text.value; + LogDebug("min-version value: " << m_minVersion); + } + } + + virtual void Verify() + { + if (m_properNamespace) { + if (m_minVersion.IsNull()) { + ThrowMsg(Exception::ParseError, + "min-version element must have value"); + } + + DPL::OptionalFloat version = ParseMinVersion(*m_minVersion); + if (version.IsNull()) { + ThrowMsg(Exception::ParseError, + "min-version element must have value" + " that can be parsed to float"); + } + + if (m_data.minVersionRequiredFound.IsNull()) { + m_data.minVersionRequiredFound = 1; + m_data.minVersionRequired = version; + LogDebug("MinVersionRequired = " << version); + } else { + ThrowMsg(Exception::ParseError, + "multiple min-version elements not allowed"); + } + } + } + + MinVersionParser(ConfigParserData& data) : + ElementParser(), + m_properNamespace(false), + m_data(data), + m_minVersion() + { + LogDebug("MinVersionParser created"); + } + + private: + bool m_properNamespace; + ConfigParserData& m_data; + DPL::OptionalString m_minVersion; + + static DPL::OptionalFloat ParseMinVersion(const DPL::String& value) + { + DPL::OptionalString normalizedValue = value; + NormalizeString(normalizedValue); + if (!(*normalizedValue).empty()) { + char* reterr = NULL; + errno = 0; + float valueFloat = + strtof(DPL::ToUTF8String(value).c_str(), &reterr); + if (errno != 0 || + std::string(reterr) == DPL::ToUTF8String(value) || + valueFloat <= 0.0) { + return DPL::OptionalFloat::Null; + } else { + return valueFloat; + } + } + return DPL::OptionalFloat::Null; + } +}; + +// tag: <back supported=true> +class BackParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + LogDebug("attribute"); + if (attribute.name == L"supported") { + if (attribute.value == L"true") { + m_backSupported = true; + } else { + m_backSupported = false; + } + } + } + + virtual void Accept(const Element&) + { + LogDebug("element"); + //if empty back element will be passed, we say true + m_data.backSupported = true; + } + + virtual void Accept(const Text&) + { + LogDebug("text"); + ThrowMsg(Exception::ParseError, "back element must be empty"); + } + + virtual void Verify() + { + m_data.backSupported = m_backSupported; + } + + BackParser(ConfigParserData& data) : + ElementParser(), + m_backSupported(false), + m_data(data) + { + } + + private: + bool m_backSupported; + ConfigParserData& m_data; +}; + +class SettingParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const XmlAttribute& attribute) + { + m_setting.m_name = attribute.name; + m_setting.m_value = attribute.value; + m_data.settingsList.insert(m_setting); + } + + virtual void Verify() + { + } + + SettingParser(ConfigParserData& data) : + ElementParser(), + m_data(data), + m_setting(L"", L"") + { + } + + private: + ConfigParserData& m_data; + ConfigParserData::Setting m_setting; +}; + +class ServiceParser : public ElementParser +{ + public: + virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, + const DPL::String& /*name*/) + { + return &IgnoringParser::Create; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if (attribute.name == L"src") { + m_src = attribute.value; + } else if (attribute.name == L"operation") { + m_operation = attribute.value; + } else if (attribute.name == L"scheme") { + m_scheme = attribute.value; + } else if (attribute.name == L"mime") { + m_mime = attribute.value; + } + } + + virtual void Accept(const Element& element) + { + LogWarning("namespace for app service = " << element.ns); + if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) { + ThrowMsg(Exception::ParseError, + "Wrong xml namespace for widget element"); + } + } + + virtual void Accept(const Text& /*text*/) + { + ThrowMsg(Exception::ParseError, "param element must be empty"); + } + + virtual void Verify() + { + if (m_src.IsNull()) { + LogWarning("service element must have target attribute"); + return; + } else if (m_operation.IsNull()) { + LogWarning("service element must have operation attribute"); + return; + } + NormalizeString(m_src); + NormalizeString(m_operation); + NormalizeString(m_scheme); + NormalizeString(m_mime); + + // verify duplicate element + DPL::String wildString(L"*/*"); + DPL::String nullString(L""); + ConfigParserData::ServiceInfo serviceInfo( + m_src.IsNull() ? nullString:*m_src, + m_operation.IsNull() ? nullString:*m_operation, + m_scheme.IsNull() ? nullString:*m_scheme, + m_mime.IsNull() ? nullString:*m_mime); + + FOREACH(iterator, m_data.appServiceList) { + if (iterator->m_operation == serviceInfo.m_operation && + // check scheme + (iterator->m_scheme == serviceInfo.m_scheme || + // check input scheme is "*/*" case + (iterator->m_scheme == wildString && + serviceInfo.m_scheme != nullString) || + // check iterator scheme is "*/*" case + (serviceInfo.m_scheme == wildString && + iterator->m_scheme != nullString)) && + + (iterator->m_mime == serviceInfo.m_mime || + // check input mime is "*/*" case + (iterator->m_mime == wildString && + serviceInfo.m_mime != nullString) || + // check iterator mime is "*/*" case + (serviceInfo.m_mime == wildString && + iterator->m_mime != nullString))) + { + ThrowMsg(Exception::ParseError, + "service operation is duplicated " + + DPL::ToUTF8String(*m_operation)); + } + } + m_data.appServiceList.push_back(serviceInfo); + } + + ServiceParser(ConfigParserData& data) : + ElementParser(), + m_src(DPL::OptionalString::Null), + m_operation(DPL::OptionalString::Null), + m_scheme(DPL::OptionalString::Null), + m_mime(DPL::OptionalString::Null), + m_data(data) + { + } + + private: + DPL::OptionalString m_src; + DPL::OptionalString m_operation; + DPL::OptionalString m_scheme; + DPL::OptionalString m_mime; + ConfigParserData& m_data; +}; + +ElementParser::ActionFunc WidgetParser::GetElementParser(const DPL::String& /*ns*/, + const DPL::String& name) +{ + FuncMap::const_iterator it = m_map.find(name); + if (it != m_map.end()) { + return it->second; + } else { + return &IgnoringParser::Create; + } +} + +WidgetParser::WidgetParser(ConfigParserData& data) : + m_data(data), + m_textDirection(Unicode::EMPTY) +{ + m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement); + m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement); + m_map[L"description"] = + DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement); + m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement); + m_map[L"license"] = + DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement); + m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement); + m_map[L"content"] = + DPL::MakeDelegate(this, &WidgetParser::OnContentElement); + m_map[L"feature"] = + DPL::MakeDelegate(this, &WidgetParser::OnFeatureElement); + m_map[L"preference"] = + DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement); + m_map[L"flash"] = DPL::MakeDelegate(this, &WidgetParser::OnFlashElement); + m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement); + m_map[L"min-version"] = + DPL::MakeDelegate(this, &WidgetParser::OnMinVersionElement); + m_map[L"back"] = DPL::MakeDelegate(this, &WidgetParser::OnBackElement); + m_map[L"pkgname"] = DPL::MakeDelegate(this, &WidgetParser::OnPkgnameElement); + m_map[L"setting"] = + DPL::MakeDelegate(this, &WidgetParser::OnSettingElement); + m_map[L"appservice"] = DPL::MakeDelegate(this, &WidgetParser::OnServiceElement); +} + +ElementParserPtr WidgetParser::OnNameElement() +{ + return ElementParserPtr(new NameParser(m_textDirection, m_data)); +} + +ElementParserPtr WidgetParser::OnAccessElement() +{ + return ElementParserPtr(new AccessParser(m_data)); +} + +ElementParserPtr WidgetParser::OnDescriptionElement() +{ + return ElementParserPtr(new DescriptionParser(m_textDirection, m_data)); +} + +ElementParserPtr WidgetParser::OnAuthorElement() +{ + return ElementParserPtr(new AuthorParser(m_textDirection, m_data)); +} + +ElementParserPtr WidgetParser::OnLicenseElement() +{ + return ElementParserPtr(new LicenseParser(m_textDirection, m_data)); +} + +ElementParserPtr WidgetParser::OnIconElement() +{ + return ElementParserPtr(new IconParser(m_data)); +} + +ElementParserPtr WidgetParser::OnContentElement() +{ + return ElementParserPtr(new ContentParser(m_data)); +} + +ElementParserPtr WidgetParser::OnFeatureElement() +{ + return ElementParserPtr(new FeatureParser(m_data)); +} + +ElementParserPtr WidgetParser::OnPreferenceElement() +{ + return ElementParserPtr(new PreferenceParser(m_data)); +} + +ElementParserPtr WidgetParser::OnFlashElement() +{ + return ElementParserPtr(new FlashParser(m_data)); +} + +ElementParserPtr WidgetParser::OnLinkElement() +{ + return ElementParserPtr(new LinkParser(m_data)); +} + +ElementParserPtr WidgetParser::OnMinVersionElement() +{ + return ElementParserPtr(new MinVersionParser(m_data)); +} + +ElementParserPtr WidgetParser::OnBackElement() +{ + return ElementParserPtr(new BackParser(m_data)); +} + +ElementParserPtr WidgetParser::OnPkgnameElement() +{ + return ElementParserPtr(new PkgnameParser(m_data)); +} + +ElementParserPtr WidgetParser::OnSettingElement() +{ + return ElementParserPtr(new SettingParser(m_data)); +} + +ElementParserPtr WidgetParser::OnServiceElement() +{ + return ElementParserPtr(new ServiceParser(m_data)); +} + +void WidgetParser::Accept(const Element& element) +{ + if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName) { + ThrowMsg(Exception::ParseError, + "Wrong xml namespace for widget element"); + } +} + +void WidgetParser::Accept(const Text& /*text*/) +{ + ThrowMsg(Exception::ParseError, "widged element must be empty"); +} + +void WidgetParser::Accept(const XmlAttribute& attribute) +{ + if (attribute.name == L"id") { + LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str()); + //If may important tests starts to fail this test we will have + //to consider commenting this test out again. + if (iri.Validate()) { + m_data.widget_id = attribute.value; + NormalizeString(m_data.widget_id); + } + } else if (attribute.name == L"version") { + m_version = attribute.value; + NormalizeString(m_version); + } else if (attribute.name == L"height") { + DPL::OptionalString value = attribute.value; + NormalizeString(value); + std::string v = DPL::ToUTF8String(*value); + + if (!v.empty()) { + unsigned char c = v.c_str()[0]; + if (c >= '0' && c <= '9') { + int val = 0; + for (size_t i = 0; i < v.size(); ++i) { + c = v.c_str()[i]; + if (c >= '0' && c <= '9') { + val *= 10; + val += (c - '0'); + } else { + break; + } + } + m_data.height = val; + } + } + } else if (attribute.name == L"width") { + DPL::OptionalString value = attribute.value; + NormalizeString(value); + std::string v = DPL::ToUTF8String(*value); + + if (!v.empty()) { + unsigned char c = v.c_str()[0]; + if (c >= '0' && c <= '9') { + int val = 0; + for (size_t i = 0; i < v.size(); ++i) { + c = v.c_str()[i]; + if (c >= '0' && c <= '9') { + val *= 10; + val += (c - '0'); + } else { + break; + } + } + m_data.width = val; + } + } + } else if (attribute.name == L"viewmodes") { + DPL::Tokenize(attribute.value, + L" ", + std::inserter(m_windowModes, + m_windowModes.end()), + true); + } else if (attribute.name == L"dir") { + m_textDirection = Unicode::ParseDirAttribute(attribute); + } else if (L"defaultlocale" == attribute.name) { + if (!m_defaultlocale) { + m_defaultlocale = attribute.value; + NormalizeString(m_defaultlocale); + if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag( + DPL::ToUTF8String(*m_defaultlocale))) { + LogWarning("Language tag: " << + m_defaultlocale << " is not valid"); + m_defaultlocale = DPL::OptionalString::Null; + } + else + LogDebug("Default Locale Found " << m_defaultlocale); + } else { + LogWarning("Ignoring subsequent default locale"); + } + } else if (DPL::StringCompare(L"xmlns", attribute.name) < 0) { + LogWarning("namespace domain" << attribute.name); + LogWarning("namespace value " << attribute.value); + DPL::OptionalString ns = attribute.value; + + if (attribute.name == L"xmlns:wac") { + m_nameSpaces.push_back(attribute.value); + } else if (attribute.name == L"xmlns:tizen") { + m_nameSpaces.push_back(attribute.value); + } else if (attribute.name == L"xmlns:jil") { + m_nameSpaces.push_back(attribute.value); + } + } +} + +void WidgetParser::Verify() +{ + FOREACH(mode, m_windowModes) { + if (L"windowed" == *mode || L"floating" == *mode || + L"fullscreen" == *mode || L"maximized" == *mode || + L"minimized" == *mode) { + m_data.windowModes.insert(*mode); + } + } + if (!m_version.IsNull()) { + Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version); + m_data.version = m_version; + } + m_data.defaultlocale = m_defaultlocale; + FOREACH(ns, m_nameSpaces) { + m_data.nameSpaces.insert(*ns); + } +} + diff --git a/src/configuration_parser/widget_parser.h b/src/configuration_parser/widget_parser.h new file mode 100644 index 0000000..d008a59 --- /dev/null +++ b/src/configuration_parser/widget_parser.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + /** + * This file have been implemented in compliance with W3C WARP SPEC. + * but there are some patent issue between W3C WARP SPEC and APPLE. + * so if you want to use this file, refer to the README file in root directory + */ +/** + * @file widget_parser.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 0.1 + * @brief + */ +#ifndef WIDGET_PARSER_H_ +#define WIDGET_PARSER_H_ + +#include "element_parser.h" +#include <list> +#include <dpl/foreach.h> +#include <dpl/wrt-dao-ro/config_parser_data.h> + +namespace ConfigurationNamespace { +static const DPL::String W3CWidgetNamespaceName = + L"http://www.w3.org/ns/widgets"; +static const DPL::String JilWidgetNamespaceName = + L"http://www.jil.org/ns/widgets1.2"; +static const DPL::String WacWidgetNamespaceNameForLinkElement = + L"http://wacapps.net/ns/widgets#"; +static const DPL::String WacWidgetNamespaceName = + L"http://wacapps.net/ns/widgets"; +static const DPL::String TizenWebAppNamespaceName = + L"http://tizen.org/ns/widgets"; +} + +namespace PluginsPrefix { +const char * const W3CPluginsPrefix = "http://www.w3.org/"; +const char * const WACPluginsPrefix = "http://wacapps.net/api/"; +const char * const TIZENPluginsPrefix = "http://tizen.org/api/"; +} + +namespace Unicode { +enum Direction +{ + LRE, + RLE, + LRO, + RLO, + EMPTY +}; +} + +class WidgetParser : public ElementParser +{ + public: + ElementParserPtr OnNameElement(); + ElementParserPtr OnDescriptionElement(); + ElementParserPtr OnAuthorElement(); + ElementParserPtr OnLicenseElement(); + ElementParserPtr OnIconElement(); + ElementParserPtr OnContentElement(); + ElementParserPtr OnFeatureElement(); + ElementParserPtr OnPreferenceElement(); + ElementParserPtr OnAccessElement(); + ElementParserPtr OnFlashElement(); + ElementParserPtr OnLinkElement(); + ElementParserPtr OnMinVersionElement(); + ElementParserPtr OnBackElement(); + ElementParserPtr OnPkgnameElement(); + ElementParserPtr OnSettingElement(); + ElementParserPtr OnServiceElement(); + + virtual ActionFunc GetElementParser(const DPL::String& ns, + const DPL::String& name); + + virtual void Accept(const Element&); + virtual void Accept(const Text&); + virtual void Accept(const XmlAttribute&); + virtual void Verify(); + + //Typedef used by RootParser + typedef WrtDB::ConfigParserData& Data; + + WidgetParser(Data&); + + private: + Data& m_data; + Unicode::Direction m_textDirection; + FuncMap m_map; + DPL::Optional<DPL::String> m_version; + std::list<DPL::String> m_windowModes; + DPL::Optional<DPL::String> m_defaultlocale; + std::list<DPL::String> m_nameSpaces; +}; + +struct IconParser; +struct ContentParser; + +#endif // WIDGET_PARSER_H_ diff --git a/src/jobs/job.cpp b/src/jobs/job.cpp new file mode 100644 index 0000000..70fef1a --- /dev/null +++ b/src/jobs/job.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <job.h> +#include <installer_controller.h> + +namespace Jobs { +Job::Job(InstallationType installType) : + m_installationType(installType), + m_UndoType(false), + m_paused(false) +{ +} + +InstallationType Job::GetInstallationType() const +{ + return m_installationType; +} + +bool Job::GetUndoType() const +{ + return m_UndoType; +} + +void Job::SetUndoType(bool flag) +{ + m_UndoType = flag; +} + +bool Job::IsPaused() const +{ + return m_paused; +} + +void Job::SetPaused(bool paused) +{ + if (paused) { + Pause(); + } else { + Resume(); + } +} + +void Job::Pause() +{ + if (m_paused) { + return; + } + + // Pause + m_paused = true; +} + +void Job::Resume() +{ + if (!m_paused) { + return; + } + + // Continue + m_paused = false; + + // Trigger next steps + CONTROLLER_POST_EVENT(InstallerController, + InstallerControllerEvents::NextStepEvent(this)); +} + +void Job::SetJobHandle(JobHandle handle) +{ + m_handle = handle; +} + +JobHandle Job::GetJobHandle() const +{ + return m_handle; +} + +void Job::SendProgress() +{ +} + +void Job::SendFinishedSuccess() +{ +} + +void Job::SendFinishedFailure() +{ +} + +void Job::SaveExceptionData(const Jobs::JobExceptionBase&) +{ +} +} //namespace Jobs diff --git a/src/jobs/job.h b/src/jobs/job.h new file mode 100644 index 0000000..877a966 --- /dev/null +++ b/src/jobs/job.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 INSTALLER_MODEL_H +#define INSTALLER_MODEL_H + +#include <dpl/task_list.h> + +namespace Jobs { +class JobExceptionBase; +/** + * @brief Defines installation and uninstallation type. + */ +enum InstallationType +{ + Installation, ///< defines install process + Uninstallation, ///< defines uninstall process + PluginInstallation ///< defines plugin installation process +}; + +typedef int JobHandle; + +class Job : + public DPL::TaskList +{ + public: + Job(InstallationType installType); + + InstallationType GetInstallationType() const; + + // Undo + void SetUndoType(bool flag); + bool GetUndoType() const; + + // Pause/resume support + bool IsPaused() const; + void SetPaused(bool paused); + void Pause(); + void Resume(); + void SetJobHandle(JobHandle handle); + JobHandle GetJobHandle() const; + virtual void SendProgress(); + virtual void SendFinishedSuccess(); + virtual void SendFinishedFailure(); + + virtual void SaveExceptionData(const Jobs::JobExceptionBase&); + private: + JobHandle m_handle; + InstallationType m_installationType; + bool m_UndoType; //TODO change name to m_AbortStarted + bool m_paused; +}; +} //namespace Jobs + +#endif // INSTALLER_MODEL_H diff --git a/src/jobs/job_base.h b/src/jobs/job_base.h new file mode 100644 index 0000000..86e1746 --- /dev/null +++ b/src/jobs/job_base.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 SRC_INSTALLER_CORE_JOBS_JOB_BASE_H +#define SRC_INSTALLER_CORE_JOBS_JOB_BASE_H + +#include <string> + +typedef std::string ProgressDescription; +typedef float ProgressPercent; + +namespace Jobs { +template<typename T_InstallationStep, + T_InstallationStep lastElement> +class JobProgressBase +{ + protected: + bool m_progressFlag; + ProgressDescription m_progresDescription; + ProgressPercent m_progresPercent; + + public: + JobProgressBase() : m_progressFlag(false), + m_progresPercent(0.0) + { + } + + void SetProgressFlag(bool flag) + { + m_progressFlag = flag; + } + bool GetProgressFlag() const + { + return m_progressFlag; + } + + ProgressDescription GetProgressDescription() const + { + return m_progresDescription; + } + + ProgressPercent GetProgressPercent() const + { + return m_progresPercent; + } + + void UpdateProgress(T_InstallationStep step, + ProgressDescription const &description) + { + m_progresPercent = + ((static_cast<ProgressPercent>(step) + 1.0) / + static_cast<ProgressPercent>(lastElement)) * 100; + m_progresDescription = description; + } +}; + +template<class T_JobStruct> +class JobContextBase +{ + public: + JobContextBase(const T_JobStruct& jobStruct) : + m_jobStruct(jobStruct) + { + } + + T_JobStruct getInstallerStruct() const + { + return m_jobStruct; + } //TODO RENAME + + protected: + T_JobStruct m_jobStruct; +}; + +template<typename T_finishedCb, typename T_progressCb> +struct JobCallbacksBase +{ + T_finishedCb finishedCallback; + T_progressCb progressCallback; + void *userParam; + + // It must be empty-constructible as a parameter of generic event + JobCallbacksBase() : + finishedCallback(0), + progressCallback(0), + userParam(0) + { + } + + JobCallbacksBase(T_finishedCb finished, + T_progressCb progress, + void *param) : + finishedCallback(finished), + progressCallback(progress), + userParam(param) + { + } +}; +} //namespace Jobs + +#endif // SRC_INSTALLER_CORE_JOBS_JOB_BASE_H diff --git a/src/jobs/job_exception_base.h b/src/jobs/job_exception_base.h new file mode 100644 index 0000000..3f12a2d --- /dev/null +++ b/src/jobs/job_exception_base.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file job_exception_base.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +#include <dpl/exception.h> + +#ifndef SRC_INSTALLER_CORE_JOBS_JOB_EXCEPTION_BASE_H_ +#define SRC_INSTALLER_CORE_JOBS_JOB_EXCEPTION_BASE_H_ + +#define DECLARE_JOB_EXCEPTION_BASE(Base, Class, Param) \ + class Class : \ + public Base { \ + public: \ + Class(const char *path, \ + const char *function, \ + int line, \ + const std::string & message = std::string()) : \ + Base(path, function, line, message) \ + { \ + m_className = # Class; \ + m_param = Param; \ + } \ + \ + Class(const char *path, \ + const char *function, \ + int line, \ + const Exception &reason, \ + const std::string & message = std::string()) : \ + Base(path, function, line, reason, message) \ + { \ + m_className = # Class; \ + m_param = Param; \ + } \ + \ + virtual int getParam() const \ + { \ + return m_param; \ + } \ + protected: \ + int m_param; \ + }; +//TODO template for m_param + +#define DECLARE_JOB_EXCEPTION(Base, Class, Param) \ + class Class : \ + public Base { \ + public: \ + Class(const char *path, \ + const char *function, \ + int line, \ + const std::string & message = std::string()) : \ + Base(path, function, line, message) \ + { \ + m_className = # Class; \ + m_param = Param; \ + } \ + \ + Class(const char *path, \ + const char *function, \ + int line, \ + const Exception &reason, \ + const std::string & message = std::string()) : \ + Base(path, function, line, reason, message) \ + { \ + m_className = # Class; \ + m_param = Param; \ + } \ + \ + virtual int getParam() const \ + { \ + return m_param; \ + } \ + }; +//TODO template for m_param + +//TODO maybe use DPL:: DECLARE_EXCEPTION_TYPE instead of creating own + +namespace Jobs { +DECLARE_JOB_EXCEPTION_BASE(DPL::Exception, JobExceptionBase, 0) +} + +#endif /* SRC_INSTALLER_CORE_JOBS_JOB_EXCEPTION_BASE_H_ */ diff --git a/src/jobs/plugin_install/job_plugin_install.cpp b/src/jobs/plugin_install/job_plugin_install.cpp new file mode 100644 index 0000000..8bf52ff --- /dev/null +++ b/src/jobs/plugin_install/job_plugin_install.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file job_plugin_install.cpp + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ +#include <plugin_install/job_plugin_install.h> +#include <plugin_install/plugin_install_task.h> +#include <widget_install/widget_installer_struct.h> //TODO remove + +//#include <plugin_logic.h> +#include "plugin_objects.h" + +namespace Jobs { +namespace PluginInstall { +JobPluginInstall::JobPluginInstall(std::string const &pluginPath, + const PluginInstallerStruct &installerStruct) : + Job(PluginInstallation), + JobContextBase<PluginInstallerStruct>(installerStruct) +{ + // + // Init installer context + // + m_context.pluginFilePath = pluginPath; + m_context.pluginHandle = INVALID_HANDLE; + m_context.installationCompleted = false; + + m_context.installerTask = this; + // + // Create main installation tasks + // + AddTask(new PluginInstallTask(&m_context)); +} + +void JobPluginInstall::SendProgress() +{ + if (GetProgressFlag() && getInstallerStruct().progressCallback != NULL) { + LogDebug("Call Plugin install progressCallback"); + getInstallerStruct().progressCallback(getInstallerStruct().userParam, + GetProgressPercent(), GetProgressDescription()); + } +} + +void JobPluginInstall::SendFinishedSuccess() +{ + PluginHandle handle = getNewPluginHandle(); + + if (handle != Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE && + isReadyToInstall()) + { + LogDebug("Call Plugin install success finishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + Exceptions::Success); + } else { + LogDebug("Call Plugin install waiting finishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + Exceptions::InstallationWaiting); + + LogInfo("Installation: " << getFilePath() << + " NOT possible"); + } +} + +void JobPluginInstall::SendFinishedFailure() +{ + LogError("Error in plugin installation step: " << m_exceptionCaught); + LogError("Message: " << m_exceptionMessage); + + LogDebug("Call Plugin install failure finishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + m_exceptionCaught); +} + +void JobPluginInstall::SaveExceptionData(const Jobs::JobExceptionBase &e) +{ + m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam()); + m_exceptionMessage = e.GetMessage(); +} +} //namespace Jobs +} //namespace PluginInstall diff --git a/src/jobs/plugin_install/job_plugin_install.h b/src/jobs/plugin_install/job_plugin_install.h new file mode 100644 index 0000000..a7fde44 --- /dev/null +++ b/src/jobs/plugin_install/job_plugin_install.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file job_plugin_install.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +#ifndef WRT_SRC_INSTALLER_CORE_JOB_JOB_PLUGIN_INSTALL_H_ +#define WRT_SRC_INSTALLER_CORE_JOB_JOB_PLUGIN_INSTALL_H_ + +//SYSTEM INCLUDES +#include <string> + +//WRT INCLUDES +#include <job.h> +#include <job_base.h> +#include <plugin_install/plugin_installer_struct.h> +#include <plugin_install/plugin_installer_context.h> + +namespace Jobs { +namespace PluginInstall { +class JobPluginInstall : + public Job, + public JobProgressBase<PluginInstallerContext::PluginInstallStep, + PluginInstallerContext::PLUGIN_INSTALL_END>, + public JobContextBase<PluginInstallerStruct> +{ + public: + static const WrtDB::DbPluginHandle INVALID_HANDLE = -1; + + public: + /** + * @brief Automaticaly sets installation process + */ + JobPluginInstall(std::string const &pluginPath, + const PluginInstallerStruct &installerStruct); + + WrtDB::DbPluginHandle getNewPluginHandle() const + { + return m_context.pluginHandle; + } + std::string getFilePath() const + { + return m_context.pluginFilePath; + } + bool isReadyToInstall() const + { + return m_context.installationCompleted; + } + + void SendProgress(); + void SendFinishedSuccess(); + void SendFinishedFailure(); + void SaveExceptionData(const Jobs::JobExceptionBase &e); + private: + //TODO move somewhere this attribute + //(as it is in all Jobs...) + PluginInstallerContext m_context; + + //TODO move it to base class of all jobs + //maybe separate JobBase class for this? + Exceptions::Type m_exceptionCaught; + std::string m_exceptionMessage; +}; +} //namespace Jobs +} //namespace PluginInstall + +#endif /* WRT_SRC_INSTALLER_CORE_JOB_JOB_PLUGIN_INSTALL_H_ */ diff --git a/src/jobs/plugin_install/plugin_install_task.cpp b/src/jobs/plugin_install/plugin_install_task.cpp new file mode 100644 index 0000000..218e10b --- /dev/null +++ b/src/jobs/plugin_install/plugin_install_task.cpp @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file install_one_task.cpp + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samgsung.com) + * @version + * @brief + */ + +//SYSTEM INCLUDES +#include <sys/types.h> +#include <sys/stat.h> +#include <dlfcn.h> + +//WRT INCLUDES +#include <dpl/log/log.h> +#include <job.h> +#include "plugin_install_task.h" +#include "job_plugin_install.h" +#include "plugin_installer_errors.h" +#include "plugin_metafile_reader.h" +#include <dpl/wrt-dao-ro/global_config.h> +//#include <plugin.h> +#include <wrt_common_types.h> +#include <dpl/wrt-dao-rw/feature_dao.h> +#include <dpl/wrt-dao-rw/plugin_dao.h> +#include "plugin_objects.h" + +using namespace WrtDB; + +namespace { +const std::string DIRECTORY_SEPARATOR = std::string("/"); +} + +#define SET_PLUGIN_INSTALL_PROGRESS(step, desc) \ + m_context->installerTask->UpdateProgress( \ + PluginInstallerContext::step, desc); + +namespace Jobs { +namespace PluginInstall { +PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) : + DPL::TaskDecl<PluginInstallTask>(this), + m_context(inCont) +{ + AddStep(&PluginInstallTask::stepCheckPluginPath); + AddStep(&PluginInstallTask::stepParseConfigFile); + AddStep(&PluginInstallTask::stepCheckIfAlreadyInstalled); + AddStep(&PluginInstallTask::stepLoadPluginLibrary); + AddStep(&PluginInstallTask::stepRegisterPlugin); + AddStep(&PluginInstallTask::stepRegisterFeatures); + AddStep(&PluginInstallTask::stepRegisterPluginObjects); + AddStep(&PluginInstallTask::stepResolvePluginDependencies); + + SET_PLUGIN_INSTALL_PROGRESS(START, "Installation initialized"); +} + +PluginInstallTask::~PluginInstallTask() +{ +} + +void PluginInstallTask::stepCheckPluginPath() +{ + LogInfo("Plugin installation: step CheckPluginPath"); + + struct stat tmp; + + if (-1 == stat(m_context->pluginFilePath.c_str(), &tmp)) { + ThrowMsg(Exceptions::PluginPathFailed, + "Stat function failed"); + } + + if (!S_ISDIR(tmp.st_mode)) { + ThrowMsg(Exceptions::PluginPathFailed, + "Invalid Directory"); + } + + SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Path to plugin verified"); +} + +void PluginInstallTask::stepParseConfigFile() +{ + LogInfo("Plugin installation: step parse config file"); + + std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR + + std::string(GlobalConfig::GetPluginMetafileName()); + + LogInfo("Plugin Config file::" << filename); + + Try + { + PluginMetafileReader reader; + reader.initialize(filename); + reader.read(m_pluginMetafile); + + SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Config file analyzed"); + } + Catch(ValidationCore::ParserSchemaException::Base) + { + LogError("Error during file processing " << filename); + ThrowMsg(Exceptions::PluginMetafileFailed, + "Metafile error"); + } +} + +void PluginInstallTask::stepCheckIfAlreadyInstalled() +{ + if (PluginDAO::isPluginInstalled(m_pluginMetafile.m_libraryName)) { + ThrowMsg(Exceptions::PluginAlreadyInstalled, + "Plugin already installed"); + } + + SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_EXISTS_CHECK, "Check if plugin exist"); +} + +void PluginInstallTask::stepLoadPluginLibrary() +{ + LogInfo("Plugin installation: step load library"); + + std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR + + m_pluginMetafile.m_libraryName; + + LogDebug("Loading plugin: " << filename); + + void *dlHandle = dlopen(filename.c_str(), RTLD_LAZY); + if (dlHandle == NULL ) { + LogError( + "Failed to load plugin: " << filename << + ". Reason: " << dlerror()); + ThrowMsg(Exceptions::PluginLibraryError, "Library error"); + } + + const class_definition_t *rawClassList = NULL; + get_widget_class_map_proc *getWidgetClassMapProcPtr = NULL; + + getWidgetClassMapProcPtr = + reinterpret_cast<get_widget_class_map_proc *>(dlsym(dlHandle, + PLUGIN_GET_CLASS_MAP_PROC_NAME)); + + if (getWidgetClassMapProcPtr) { + rawClassList = (*getWidgetClassMapProcPtr)(); + } else { + rawClassList = + static_cast<const class_definition_t *>(dlsym(dlHandle, + PLUGIN_CLASS_MAP_NAME)); + } + + if (rawClassList == NULL) { + dlclose(dlHandle); + LogError("Failed to read class name" << filename); + ThrowMsg(Exceptions::PluginLibraryError, "Library error"); + } + + m_libraryObjects = PluginObjectsPtr(new PluginObjects()); + const class_definition_t *rawClassListIterator = rawClassList; + + LogInfo("#####"); + LogInfo("##### Plugin: " << filename << " supports new plugin API"); + LogInfo("#####"); + + while (rawClassListIterator->parent_name != NULL && + rawClassListIterator->object_name != NULL && + rawClassListIterator->js_class_template != NULL) { + LogInfo("##### [" << rawClassListIterator->object_name << "]: "); + LogInfo("##### Parent: " << rawClassListIterator->parent_name); + LogInfo("#####"); + + m_libraryObjects->addObjects(rawClassListIterator->parent_name, + rawClassListIterator->object_name); + + ++rawClassListIterator; +} + +// Unload library +if (dlclose(dlHandle) != 0) { + LogError("Cannot close plugin handle"); +} else { + LogDebug("Library is unloaded"); +} + + // Load export table + LogDebug("Library successfuly loaded and parsed"); + + SET_PLUGIN_INSTALL_PROGRESS(LOADING_LIBRARY, "Library loaded and analyzed"); + //TODO unload library; +} + +void PluginInstallTask::stepRegisterPlugin() +{ + LogInfo("Plugin installation: step register Plugin"); + + m_pluginHandle = + PluginDAO::registerPlugin(m_pluginMetafile, m_context->pluginFilePath); + + SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered"); +} + +void PluginInstallTask::stepRegisterFeatures() +{ + LogInfo("Plugin installation: step register features"); + + FOREACH(it, m_pluginMetafile.m_featureContainer) + { + LogError("PluginHandle: " << m_pluginHandle); + FeatureDAO::RegisterFeature(*it, m_pluginHandle); + } + SET_PLUGIN_INSTALL_PROGRESS(REGISTER_FEATURES, "Features registered"); +} + +void PluginInstallTask::stepRegisterPluginObjects() +{ + LogInfo("Plugin installation: step register objects"); + + //register implemented objects + PluginObjects::ObjectsPtr objects = + m_libraryObjects->getImplementedObject(); + + FOREACH(it, *objects) + { + PluginDAO::registerPluginImplementedObject(*it, m_pluginHandle); + } + + //register requiredObjects + objects = m_libraryObjects->getDependentObjects(); + + FOREACH(it, *objects) + { + if (m_libraryObjects->hasObject(*it)) { + LogDebug("Dependency from the same library. ignored"); + continue; + } + + PluginDAO::registerPluginRequiredObject(*it, m_pluginHandle); + } + + SET_PLUGIN_INSTALL_PROGRESS(REGISTER_OBJECTS, "Plugin Objects registered"); +} + +void PluginInstallTask::stepResolvePluginDependencies() +{ + LogInfo("Plugin installation: step resolve dependencies "); + + PluginHandleSetPtr handles = PluginHandleSetPtr(new PluginHandleSet); + + DbPluginHandle handle = INVALID_PLUGIN_HANDLE; + + //register requiredObjects + FOREACH(it, *(m_libraryObjects->getDependentObjects())) + { + if (m_libraryObjects->hasObject(*it)) { + LogDebug("Dependency from the same library. ignored"); + continue; + } + + handle = PluginDAO::getPluginHandleForImplementedObject(*it); + if (handle == INVALID_PLUGIN_HANDLE) { + LogError("Library implementing: " << *it << " NOT FOUND"); + PluginDAO::setPluginInstallationStatus( + m_pluginHandle, + PluginDAO::INSTALLATION_WAITING); + return; + } + + handles->insert(handle); + } + + PluginDAO::registerPluginLibrariesDependencies(m_pluginHandle, handles); + + PluginDAO::setPluginInstallationStatus(m_pluginHandle, + PluginDAO::INSTALLATION_COMPLETED); + + //Installation completed + m_context->pluginHandle = m_pluginHandle; + m_context->installationCompleted = true; + + SET_PLUGIN_INSTALL_PROGRESS(RESOLVE_DEPENDENCIES, "Dependencies resolved"); +} + +#undef SET_PLUGIN_INSTALL_PROGRESS +} //namespace Jobs +} //namespace PluginInstall diff --git a/src/jobs/plugin_install/plugin_install_task.h b/src/jobs/plugin_install/plugin_install_task.h new file mode 100644 index 0000000..f3eaa99 --- /dev/null +++ b/src/jobs/plugin_install/plugin_install_task.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file install.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samgsung.com) + * @version + * @brief + */ + +#ifndef INSTALL_H_ +#define INSTALL_H_ + +//WRT INCLUDES +#include <dpl/task.h> +#include "plugin_installer_context.h" +#include "plugin_objects.h" + +namespace Jobs { +namespace PluginInstall { +class PluginInstallTask : + public DPL::TaskDecl<PluginInstallTask> +{ + public: + PluginInstallTask(PluginInstallerContext *inCont); + virtual ~PluginInstallTask(); + + private: + //data + PluginInstallerContext *m_context; + + //PluginMetafile + WrtDB::PluginMetafileData m_pluginMetafile; + + //Plugin LibraryObjects + PluginObjectsPtr m_libraryObjects; + + WrtDB::DbPluginHandle m_pluginHandle; + + //steps + void stepCheckPluginPath(); + void stepParseConfigFile(); + void stepCheckIfAlreadyInstalled(); + void stepLoadPluginLibrary(); + void stepRegisterPlugin(); + void stepRegisterFeatures(); + void stepRegisterPluginObjects(); + void stepResolvePluginDependencies(); +}; +} //namespace Jobs +} //namespace PluginInstall + +#endif /* INSTALL_H_ */ diff --git a/src/jobs/plugin_install/plugin_installer_context.h b/src/jobs/plugin_install/plugin_installer_context.h new file mode 100644 index 0000000..026074a --- /dev/null +++ b/src/jobs/plugin_install/plugin_installer_context.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file plugin_installer_structs.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief Definition file of plugin installer tasks data structures + */ +#ifndef WRT_SRC_INSTALLERCORE_PLUGININSTALLERTASKS_PLUGININSTALLERCONTEXT_H_ +#define WRT_SRC_INSTALLERCORE_PLUGININSTALLERTASKS_PLUGININSTALLERCONTEXT_H_ + +#include <string> +#include <dpl/wrt-dao-ro/feature_dao_read_only.h> +//#include <plugin_model.h> + +using namespace WrtDB; + +namespace Jobs { +namespace PluginInstall { +class JobPluginInstall; +} +} + +struct PluginInstallerContext +{ + enum PluginInstallStep + { + START, + PLUGIN_PATH, + CONFIG_FILE, + PLUGIN_EXISTS_CHECK, + LOADING_LIBRARY, + REGISTER_PLUGIN, + REGISTER_FEATURES, + REGISTER_OBJECTS, + RESOLVE_DEPENDENCIES, + PLUGIN_INSTALL_END + }; + + std::string pluginFilePath; ///< plugin directory + WrtDB::DbPluginHandle pluginHandle; + // if this value is true the plugin model may be created + // if not plugin installation has failed from some reason + bool installationCompleted; + + //used to set installation progress + Jobs::PluginInstall::JobPluginInstall* installerTask; +}; + +#endif // WRT_SRC_INSTALLERCORE_PLUGININSTALLERTASKS_PLUGININSTALLERCONTEXT_H_ diff --git a/src/jobs/plugin_install/plugin_installer_errors.h b/src/jobs/plugin_install/plugin_installer_errors.h new file mode 100644 index 0000000..35f0353 --- /dev/null +++ b/src/jobs/plugin_install/plugin_installer_errors.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin_installer_errors.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samgsung.com) + * @version + * @brief + */ + +#ifndef \ + WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_INSTALLER_ERRORS_H_ +#define \ + WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_INSTALLER_ERRORS_H_ + +#include <job_exception_base.h> + +namespace Jobs { +namespace PluginInstall { +namespace Exceptions { +enum Type +{ + Success, ///< Success + + WrongPluginPath, ///< ? + MetafileError, ///< ? + AlreadyInstalled, ///< ? + LoadingLibraryError, ///< Loading library by dlopen failed. + /// It may be caused by missing symbols + InstallationWaiting, /// Installation failed due to dependencies + Unknown ///< Temporary error. Try to not use this. +}; + +DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, Unknown) +DECLARE_JOB_EXCEPTION(Base, PluginPathFailed, WrongPluginPath) +DECLARE_JOB_EXCEPTION(Base, PluginMetafileFailed, MetafileError) +DECLARE_JOB_EXCEPTION(Base, PluginAlreadyInstalled, AlreadyInstalled) +DECLARE_JOB_EXCEPTION(Base, PluginLibraryError, LoadingLibraryError) +DECLARE_JOB_EXCEPTION(Base, InstallationWaitingError, InstallationWaiting) +DECLARE_JOB_EXCEPTION(Base, UnknownError, Unknown) +} //namespace +} //namespace +} //namespace + +#endif /* WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_INSTALLER_ERRORS_H_ */ + diff --git a/src/jobs/plugin_install/plugin_installer_struct.h b/src/jobs/plugin_install/plugin_installer_struct.h new file mode 100644 index 0000000..ef69d6f --- /dev/null +++ b/src/jobs/plugin_install/plugin_installer_struct.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin_installer_struct.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 1.0 + * @brief Implementation file for widget installer struct + */ +#ifndef WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_PLUGIN_INSTALLER_STRUCT_H_ +#define WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_PLUGIN_INSTALLER_STRUCT_H_ + +#include <job_base.h> +#include <plugin_install/plugin_installer_errors.h> + +//Plugin Installer typedefs +typedef void (*PluginInstallerFinishedCallback)( + void *userParam, + Jobs::PluginInstall::Exceptions::Type); + +//installer progress +typedef void (*PluginInstallerProgressCallback)( + void *userParam, + ProgressPercent percent, + const ProgressDescription &description); + +//Plugin Installetion Struct +typedef Jobs::JobCallbacksBase<PluginInstallerFinishedCallback, + PluginInstallerProgressCallback> +PluginInstallerStruct; + +#endif // WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_PLUGIN_INSTALLER_STRUCT_H_ diff --git a/src/jobs/plugin_install/plugin_metafile_reader.cpp b/src/jobs/plugin_install/plugin_metafile_reader.cpp new file mode 100644 index 0000000..f8b91e5 --- /dev/null +++ b/src/jobs/plugin_install/plugin_metafile_reader.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin_metafile_reader.cpp + * @author Grzegorz Krawczyk(g.krawczyk@samsung.com) + * @version 1.0 + * @brief + */ + +#include "plugin_metafile_reader.h" + +using namespace WrtDB; + +namespace { +const std::string XML_NAMESPACE = ""; + +const std::string TOKEN_LIBRARY_NAME = "library-name"; +const std::string TOKEN_FEATURE_INSTALL_URI = "feature-install-uri"; +const std::string TOKEN_FEATURE_KEY_CN = "feature-key-cn"; +const std::string TOKEN_FEATURE_ROOT_CN = "feature-root-cn"; +const std::string TOKEN_FEATURE_ROOT_FINGERPRINT = "feature-root-fingerprint"; +const std::string TOKEN_API_FEATURE = "api-feature"; +const std::string TOKEN_NAME = "name"; +const std::string TOKEN_DEVICECAPABILITY = "device-capability"; +} + +PluginMetafileReader::PluginMetafileReader() : m_parserSchema(this) +{ + m_parserSchema.addEndTagCallback( + TOKEN_LIBRARY_NAME, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndLibraryName); + + m_parserSchema.addEndTagCallback( + TOKEN_FEATURE_INSTALL_URI, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndFeatureInstallURI); + + m_parserSchema.addEndTagCallback( + TOKEN_FEATURE_KEY_CN, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndFeatureKeyCN); + + m_parserSchema.addEndTagCallback( + TOKEN_FEATURE_ROOT_CN, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndFeatureRootCN); + + m_parserSchema.addEndTagCallback( + TOKEN_FEATURE_ROOT_FINGERPRINT, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndFeatureRootFingerprint); + + m_parserSchema.addEndTagCallback( + TOKEN_API_FEATURE, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndApiFeature); + + m_parserSchema.addEndTagCallback( + TOKEN_NAME, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndName); + + m_parserSchema.addEndTagCallback( + TOKEN_DEVICECAPABILITY, + XML_NAMESPACE, + &PluginMetafileReader::tokenEndDeviceCapability); +} + +void PluginMetafileReader::blankFunction(PluginMetafileData & /* data */) +{ +} + +void PluginMetafileReader::tokenEndLibraryName(PluginMetafileData &data) +{ + data.m_libraryName = m_parserSchema.getText(); +} + +void PluginMetafileReader::tokenEndFeatureInstallURI(PluginMetafileData &data) +{ + data.m_featuresInstallURI = m_parserSchema.getText(); +} + +void PluginMetafileReader::tokenEndFeatureKeyCN(PluginMetafileData &data) +{ + data.m_featuresKeyCN = m_parserSchema.getText(); +} + +void PluginMetafileReader::tokenEndFeatureRootCN(PluginMetafileData &data) +{ + data.m_featuresRootCN = m_parserSchema.getText(); +} + +void PluginMetafileReader::tokenEndFeatureRootFingerprint( + PluginMetafileData &data) +{ + data.m_featuresRootFingerprint = m_parserSchema.getText(); +} + +void PluginMetafileReader::tokenEndApiFeature(PluginMetafileData &data) +{ + data.m_featureContainer.insert(m_feature); +} + +void PluginMetafileReader::tokenEndName(PluginMetafileData & /* data */) +{ + m_feature.m_name = m_parserSchema.getText(); +} + +void PluginMetafileReader::tokenEndDeviceCapability(PluginMetafileData& /*data*/) +{ + m_feature.m_deviceCapabilities.insert(m_parserSchema.getText()); +} + diff --git a/src/jobs/plugin_install/plugin_metafile_reader.h b/src/jobs/plugin_install/plugin_metafile_reader.h new file mode 100644 index 0000000..8de27ed --- /dev/null +++ b/src/jobs/plugin_install/plugin_metafile_reader.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin_metafile_reader.h + * @author Grzegorz Krawczyk(g.krawczyk@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_METAFILE_READER_H_ +#define WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_METAFILE_READER_H_ + +#include <dpl/wrt-dao-ro/common_dao_types.h> +#include <vcore/ParserSchema.h> + +class PluginMetafileReader +{ + public: + PluginMetafileReader(); + + void initialize(const std::string &filename) + { + m_parserSchema.initialize(filename, + true, + ValidationCore::SaxReader::VALIDATION_DTD, + std::string()); + } + + void read(WrtDB::PluginMetafileData &data) + { + m_parserSchema.read(data); + } + + private: + void blankFunction(WrtDB::PluginMetafileData &data); + + void tokenEndLibraryName(WrtDB::PluginMetafileData &data); + void tokenEndFeatureInstallURI(WrtDB::PluginMetafileData &data); + void tokenEndFeatureKeyCN(WrtDB::PluginMetafileData &data); + void tokenEndFeatureRootCN(WrtDB::PluginMetafileData &data); + void tokenEndFeatureRootFingerprint(WrtDB::PluginMetafileData &data); + void tokenEndApiFeature(WrtDB::PluginMetafileData &data); + void tokenEndName(WrtDB::PluginMetafileData &data); + void tokenEndDeviceCapability(WrtDB::PluginMetafileData &data); + + WrtDB::PluginMetafileData::Feature m_feature; + + ValidationCore::ParserSchema<PluginMetafileReader, + WrtDB::PluginMetafileData> m_parserSchema; +}; + +#endif diff --git a/src/jobs/plugin_install/plugin_objects.cpp b/src/jobs/plugin_install/plugin_objects.cpp new file mode 100644 index 0000000..71e9131 --- /dev/null +++ b/src/jobs/plugin_install/plugin_objects.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin_objects.h + * @author Grzegorz Krawczyk (g.krawczyk@samgsung.com) + * @version + * @brief + */ +#include <string> +#include <dpl/log/log.h> +#include "plugin_objects.h" + +namespace { +const char* SEPARATOR = "."; +const std::string GLOBAL_OBJECT_NAME = "GLOBAL_OBJECT"; + +std::string normalizeName(const std::string& objectName) +{ + if (objectName.empty()) { + LogError("Normalize name, name size is 0"); + return objectName; + } + + if (!objectName.compare(0, GLOBAL_OBJECT_NAME.size(), + GLOBAL_OBJECT_NAME)) { + return objectName; + } + + //each object in storage has name started from $GLOBAL_OBJECT_NAME$ + return GLOBAL_OBJECT_NAME + std::string(SEPARATOR) + objectName; +} + +std::string normalizeName(const std::string& objectName, + const std::string& parentName) +{ + if (objectName.empty() || parentName.empty()) { + LogError("Normalize name, name size or parent name size is 0"); + return std::string(); + } + + std::string normalizedName; + normalizedName = normalizeName(parentName) + + std::string(SEPARATOR) + objectName; + + return normalizedName; +} +} + +PluginObjects::PluginObjects() +{ + m_implemented = ObjectsPtr(new Objects()); + m_dependent = ObjectsPtr(new Objects()); +} + +PluginObjects::ObjectsPtr PluginObjects::getImplementedObject() const +{ + return m_implemented; +} + +PluginObjects::ObjectsPtr PluginObjects::getDependentObjects() const +{ + return m_dependent; +} + +void PluginObjects::addObjects(const std::string& parentName, + const std::string& name) +{ + addImplementedObject(normalizeName(name, parentName)); + addDependentObject(normalizeName(parentName)); +} + +void PluginObjects::addDependentObject(const std::string& value) +{ + if (!value.compare(GLOBAL_OBJECT_NAME)) { + //dont add dependency to GLOBAL_OBJECT + return; + } + m_dependent->insert(value); +} + +bool PluginObjects::hasObject(const std::string& name) const +{ + return m_implemented->find(name) != m_implemented->end(); +} + +void PluginObjects::addImplementedObject(const std::string& value) +{ + m_implemented->insert(value); +} diff --git a/src/jobs/plugin_install/plugin_objects.h b/src/jobs/plugin_install/plugin_objects.h new file mode 100644 index 0000000..95696d8 --- /dev/null +++ b/src/jobs/plugin_install/plugin_objects.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin_objects.h + * @author Grzegorz Krawczyk(g.krawczyk@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_OBJECTS_H_ +#define WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_OBJECTS_H_ + +#include <dpl/shared_ptr.h> +#include <string> +#include <set> +#include <list> + +#include <dpl/wrt-dao-ro/common_dao_types.h> +//TODO TO BE MOVED SOMEWHERE ELSE +// AS OTHER MODULES (LIKE DAO) USE IT + +class PluginObjects : public WrtDB::PluginObjectsDAO +{ + public: + explicit PluginObjects(); + + //getters for objects from library + ObjectsPtr getImplementedObject() const; + ObjectsPtr getDependentObjects() const; + + //add object declaration + void addObjects(const std::string& parentName, + const std::string& name); + + //check if library implemements object given as name + bool hasObject(const std::string& name) const; + + private: + void addImplementedObject(const std::string& value); + void addDependentObject(const std::string& value); +}; + +typedef DPL::SharedPtr<PluginObjects> PluginObjectsPtr; + +/** + +* Plugin export names + +*/ +#define PLUGIN_GET_CLASS_MAP_PROC_NAME "get_widget_class_map" +#define PLUGIN_CLASS_MAP_NAME "class_map" + +typedef struct class_definition_s +{ + const char *parent_name; + const char *object_name; + const void *js_class_template; + //class options may be null - default + void *class_options; +} class_definition_t; + +/** + +* Plugin export typedefs + +*/ +typedef const class_definition_t *class_definition_ptr_t; +typedef const class_definition_t* (*get_widget_class_map_proc)(); + +#endif diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp new file mode 100644 index 0000000..114878d --- /dev/null +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -0,0 +1,492 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file job_widget_install.cpp + * @author Radoslaw Wicik r.wicik@samsung.com + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for main installer task + */ +#include <dpl/noncopyable.h> +#include <dpl/abstract_waitable_input_adapter.h> +#include <dpl/abstract_waitable_output_adapter.h> +#include <dpl/zip_input.h> +#include <dpl/scoped_ptr.h> +#include <dpl/binary_queue.h> +#include <dpl/copy.h> +#include <dpl/assert.h> +#include <dpl/sstream.h> +#include "root_parser.h" +#include "widget_parser.h" +#include "parser_runner.h" +#include <widget_install/job_widget_install.h> +#include <widget_install/task_parental_mode.h> +#include <widget_install/task_unzip.h> +#include <widget_install/task_certify.h> +#include <widget_install/task_widget_config.h> +#include <widget_install/task_db_update.h> +#include <widget_install/task_ace_check.h> +#include <widget_install/task_smack.h> +#include <widget_install/task_desktop_file.h> +#include <widget_install/task_private_storage.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <string> +#include <dpl/wrt-dao-rw/widget_dao.h> //TODO remove +#include <dpl/wrt-dao-ro/widget_dao_read_only.h> +#include <dpl/wrt-dao-rw/global_dao.h> // TODO remove +#include <aul.h> +#include <dpl/localization/w3c_file_localization.h> + +using namespace WrtDB; + +namespace // anonymous +{ +const char * const CONFIG_XML = "config.xml"; + +struct PathAndFilePair +{ + std::string path; + std::string file; + + PathAndFilePair(const std::string &p, + const std::string &f) : + path(p), + file(f) + { + } +}; + +PathAndFilePair SplitFileAndPath(const std::string &filePath) +{ + std::string::size_type position = filePath.rfind('/'); + + // Is this only a file without a path ? + if (position == std::string::npos) { + return PathAndFilePair(std::string(), filePath); + } + + // This is full file-path pair + return PathAndFilePair(filePath.substr(0, + position), + filePath.substr(position + 1)); +} + +class InstallerTaskFail : + public DPL::TaskDecl<InstallerTaskFail> +{ + private: + bool m_deferred; + + void StepFail() + { + if (m_deferred) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred, + "Widget installation or update deferred!"); + } else { + ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed, + "Widget installation or update not allowed!"); + } + } + + public: + InstallerTaskFail(bool deferred) : + DPL::TaskDecl<InstallerTaskFail>(this), + m_deferred(deferred) + { + AddStep(&InstallerTaskFail::StepFail); + } +}; +} // namespace anonymous + +namespace Jobs { +namespace WidgetInstall { +JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, + const WidgetInstallationStruct &installerStruct) : + Job(Installation), + JobContextBase<WidgetInstallationStruct>(installerStruct), + m_exceptionCaught(Exceptions::Success) +{ + // Configure installation + ConfigureResult result = ConfigureInstallation(widgetPath); + + if (result == ConfigureResult::Ok) { + LogInfo("Configure installation succeeded"); + + // Create installation tasks + AddTask(new TaskParentalMode(m_installerContext)); + AddTask(new TaskUnzip(m_installerContext)); + AddTask(new TaskWidgetConfig(m_installerContext)); + AddTask(new TaskCertify(m_installerContext)); + AddTask(new TaskDbUpdate(m_installerContext)); + // TODO: Update progress information for this task + + AddTask(new TaskAceCheck(m_installerContext)); + //This is sort of quick solution, because ACE verdicts are based upon + //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate + //task. + AddTask(new TaskSmack(m_installerContext)); + + AddTask(new TaskDesktopFile(m_installerContext)); + AddTask(new TaskPrivateStorage(m_installerContext)); + } else if (result == ConfigureResult::Deferred) { + // Installation is deferred + LogInfo("Configure installation deferred"); + + AddTask(new InstallerTaskFail(true)); + } else if (result == ConfigureResult::Failed) { + // Installation is not allowed to proceed due to widget update policy + LogWarning("Configure installation failed!"); + + AddTask(new InstallerTaskFail(false)); + } else { + Assert(false && "Invalid configure result!"); + } +} + +DPL::Optional<WidgetHandle> JobWidgetInstall::getNewWidgetHandle() const +{ + return m_installerContext.widgetHandle; +} + +bool JobWidgetInstall::getUnzipStartedFlag() const +{ + return m_installerContext.unzipStarted; +} + +bool JobWidgetInstall::getUnzipFinishedFlag() const +{ + return m_installerContext.unzipFinished; +} + +JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( + const std::string &widgetPath) +{ + // Detect widget update + WidgetUpdateInfo update = detectWidgetUpdate(widgetPath); + + LogInfo( + "Widget install/update: incoming guid = '" << + update.incomingGUID << "'"); + LogInfo( + "Widget install/update: incoming version = '" << + update.incomingVersion << "'"); + + // Check policy + WidgetUpdateMode::Type updateTypeCheckBit; + + if (update.existingWidgetInfo.isExist == false) { + LogInfo("Widget info does not exist"); + updateTypeCheckBit = WidgetUpdateMode::NotInstalled; + } else { + LogInfo("Widget info exists. Handle: " << + update.existingWidgetInfo.existingHandle); + + DPL::OStringStream pkgName; + DPL::OptionalString pkgname = + WidgetDAOReadOnly(update.existingWidgetInfo.existingHandle).getPkgname(); + + if(pkgname.IsNull()) { + LogInfo("But widget package name doesn't exist"); + return ConfigureResult::Failed; + } + + LogInfo("Widget model exists. Package name: " << pkgName); + if (aul_app_is_running(DPL::ToUTF8String(*pkgname).c_str())) { + // Must be deferred when update in progress + if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) { + LogInfo( + "Widget is already running. Policy is update according to WAC"); + LogInfo("Installation deferred: " << widgetPath); + + GlobalDAO::AddDefferedWidgetPackageInstallation( + DPL::FromUTF8String(widgetPath)); + + return ConfigureResult::Deferred; + } else { + LogInfo( + "Widget is already running. Policy is not update according to WAC"); + LogInfo("Installation aborted: " << widgetPath); + + return ConfigureResult::Failed; + } + } + + OptionalWidgetVersion existingVersion; + existingVersion = update.existingWidgetInfo.existingVersion; + OptionalWidgetVersion incomingVersion = update.incomingVersion; + + updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion, + incomingVersion); + } + + // Calc proceed flag + bool canProceed = (m_jobStruct.updateMode & updateTypeCheckBit) > 0; + + LogInfo("Whether widget policy allow proceed: " << canProceed); + + // Init installer context + m_installerContext.widgetFilePath = widgetPath; + m_installerContext.tempWidgetPath = std::string(); + m_installerContext.widgetConfig = WidgetRegisterInfo(); + m_installerContext.unzipStarted = false; + m_installerContext.unzipFinished = false; + m_installerContext.installStep = InstallerContext::INSTALL_START; + m_installerContext.job = this; + m_installerContext.existingWidgetInfo = update.existingWidgetInfo; + m_installerContext.widgetConfig.shareHref = std::string(); + + // Return result + return canProceed ? ConfigureResult::Ok : ConfigureResult::Failed; +} + +WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy( + const OptionalWidgetVersion &existingVersion, + const OptionalWidgetVersion &incomingVersion) const +{ + // Widget is installed, check versions + if (!existingVersion && !incomingVersion) { + return WidgetUpdateMode::ExistingVersionEqual; + } else if (!existingVersion && !!incomingVersion) { + return WidgetUpdateMode::ExistingVersionNewer; + } else if (!!existingVersion && !incomingVersion) { + return WidgetUpdateMode::ExistingVersionOlder; + } else { + LogInfo("Existing widget: version = '" << *existingVersion << "'"); + + if (!existingVersion->IsWac() && !incomingVersion->IsWac()) { + return WidgetUpdateMode::BothVersionsNotStd; + } else if (!existingVersion->IsWac()) { + return WidgetUpdateMode::ExistingVersionNotStd; + } else if (!incomingVersion->IsWac()) { + return WidgetUpdateMode::IncomingVersionNotStd; + } else { + // Both versions are WAC-comparable. Do compare. + if (*incomingVersion == *existingVersion) { + return WidgetUpdateMode::ExistingVersionEqual; + } else if (*incomingVersion > *existingVersion) { + return WidgetUpdateMode::ExistingVersionOlder; + } else { + return WidgetUpdateMode::ExistingVersionNewer; + } + } + } +} + +WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate( + const std::string &widgetPath) +{ + LogInfo("Checking up widget package for config.xml..."); + + Try + { + // Open zip file + DPL::ScopedPtr<DPL::ZipInput> zipFile( + new DPL::ZipInput(widgetPath)); + + // Open config.xml file + DPL::ScopedPtr<DPL::ZipInput::File> configFile( + zipFile->OpenFile(CONFIG_XML)); + + // Extract config + DPL::BinaryQueue buffer; + DPL::AbstractWaitableInputAdapter inputAdapter(configFile.Get()); + DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer); + DPL::Copy(&inputAdapter, &outputAdapter); + + // Parse config + ParserRunner parser; + ConfigParserData configInfo; + + parser.Parse(&buffer, + ElementParserPtr( + new RootParser<WidgetParser>(configInfo, + DPL::FromUTF32String( + L"widget")))); + + // Check widget id + DPL::OptionalString widgetGUID = configInfo.widget_id; + + if (widgetGUID.IsNull()) { + LogDebug("Installed widget has no GUID"); + return WidgetUpdateInfo(); + } + + LogDebug("Installed widget GUID: " << *widgetGUID); + + // Locate widget ID with this GUID + // Incoming widget version + OptionalWidgetVersion widgetVersion; + if (!configInfo.version.IsNull()) { + widgetVersion = + DPL::Optional<WidgetVersion>( + WidgetVersion(*configInfo.version)); + } + + try + { + // Search widget handle by GUID + WidgetDAO dao(widgetGUID); + return WidgetUpdateInfo( + widgetGUID, + widgetVersion, + WidgetUpdateInfo::ExistingWidgetInfo( + dao.getHandle(), dao.getVersion())); + } + Catch(WidgetDAO::Exception::WidgetNotExist){ + // GUID isn't installed + return WidgetUpdateInfo( + widgetGUID, + widgetVersion, + WidgetUpdateInfo::ExistingWidgetInfo()); + } + } + Catch(DPL::ZipInput::Exception::OpenFailed) + { + LogDebug("Failed to open widget package"); + return WidgetUpdateInfo(); + } + Catch(DPL::ZipInput::Exception::OpenFileFailed) + { + LogDebug("Failed to open config.xml file"); + return WidgetUpdateInfo(); + } + Catch(DPL::CopyFailed) + { + LogDebug("Failed to extract config.xml file"); + return WidgetUpdateInfo(); + } + Catch(ElementParser::Exception::ParseError) + { + LogDebug("Failed to parse config.xml file"); + return WidgetUpdateInfo(); + } +} + +void JobWidgetInstall::SendProgress() +{ + if (GetProgressFlag() != false) { + if (getInstallerStruct().progressCallback != NULL) { + + LogDebug("Call widget install progressCallbak"); + getInstallerStruct().progressCallback(getInstallerStruct().userParam, + GetProgressPercent(),GetProgressDescription()); + } + } +} + +void JobWidgetInstall::SendFinishedSuccess() +{ + //inform widget info + JobWidgetInstall::displayWidgetInfo(); + + DPL::Optional<WidgetHandle> handle = getNewWidgetHandle(); + const WidgetHandle INVALID_WIDGET_HANDLE = 0; + + LogDebug("Call widget install successfinishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + !!handle ? *handle : INVALID_WIDGET_HANDLE, Exceptions::Success); +} + +void JobWidgetInstall::SendFinishedFailure() +{ + LogError("Error in installation step: " << m_exceptionCaught); + LogError("Message: " << m_exceptionMessage); + DPL::Optional<WidgetHandle> handle = getNewWidgetHandle(); + const WidgetHandle INVALID_WIDGET_HANDLE = 0; + + LogDebug("Call widget install failure finishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + !!handle ? *handle : INVALID_WIDGET_HANDLE, m_exceptionCaught); +} + +void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e) +{ + m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam()); + m_exceptionMessage = e.GetMessage(); +} + +void JobWidgetInstall::displayWidgetInfo() +{ + DPL::Optional<WidgetHandle> handle = getNewWidgetHandle(); + Assert(!!handle); + + WidgetDAO dao(*handle); + + std::ostringstream out; + WidgetLocalizedInfo localizedInfo = + W3CFileLocalization::getLocalizedInfo(*handle); + + out << std::endl << + "===================================== INSTALLED WIDGET INFO ========="\ + "============================"; + out << std::endl << "Name: " << localizedInfo.name; + WidgetSize size = dao.getPreferredSize(); + out << std::endl << "Width: " << size.width; + out << std::endl << "Height: " << size.height; + out << std::endl << "Start File: " << + W3CFileLocalization::getStartFile(*handle); + out << std::endl << "Version: " << dao.getVersion(); + out << std::endl << "Licence: " << + localizedInfo.license; + out << std::endl << "Licence Href: " << + localizedInfo.licenseHref; + out << std::endl << "Description: " << + localizedInfo.description; + out << std::endl << "Widget Id: " << dao.getGUID(); + out << std::endl << "Widget recognized: " << dao.isRecognized(); + out << std::endl << "Widget wac signed: " << dao.isWacSigned(); + out << std::endl << "Widget distributor signed: " << + dao.isDistributorSigned(); + out << std::endl << "Widget trusted: " << dao.isTrusted(); + + OptionalWidgetIcon icon = W3CFileLocalization::getIcon(*handle); + DPL::OptionalString iconSrc = + !!icon ? icon->src : DPL::OptionalString::Null; + out << std::endl << "Icon: " << iconSrc; + + out << std::endl << "Preferences:"; + { + PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList(); + FOREACH(it, list) + { + out << std::endl << " Key: " << + it->key_name; + out << std::endl << " Readonly: " << + it->readonly; + } + } + + out << std::endl << "Features:"; + { + WidgetFeatureSet list = dao.getFeaturesList(); + FOREACH(it, list) + { + out << std::endl << " Name: " << it->name; + out << std::endl << " Required: " << it->required; + out << std::endl << " Params:"; + } + } + + out << std::endl << "Back Supported: " << + (dao.getBackSupported() ? "YES" : "NO"); + + out << std::endl; + + LogInfo(out.str()); +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/job_widget_install.h b/src/jobs/widget_install/job_widget_install.h new file mode 100644 index 0000000..8822978 --- /dev/null +++ b/src/jobs/widget_install/job_widget_install.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file job_widget_install.h + * @author Radoslaw Wicik r.wicik@samsung.com + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for main installer task + */ +#ifndef WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_ +#define WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_ + +#include <dpl/optional.h> +#include <dpl/string.h> +#include <job.h> +#include <job_base.h> +#include <dpl/utils/widget_version.h> +#include <widget_install/widget_install_context.h> +#include <widget_install/widget_update_info.h> +#include "widget_installer_struct.h" + +namespace Jobs { +namespace WidgetInstall { +class JobWidgetInstall : + public Job, + public JobProgressBase<InstallerContext::InstallStep, + InstallerContext::INSTALL_END>, + public JobContextBase<WidgetInstallationStruct> //TODO typedef +{ + private: + typedef DPL::Optional<WidgetHandle> OptionalWidgetHandle; + + InstallerContext m_installerContext; + + //TODO move it to base class of all jobs + Exceptions::Type m_exceptionCaught; + std::string m_exceptionMessage; + WidgetUpdateInfo m_widgetUpdateInfo; + + enum class ConfigureResult + { + Ok, Failed, Deferred + }; + + ConfigureResult ConfigureInstallation(const std::string &widgetPath); + WidgetUpdateInfo detectWidgetUpdate(const std::string &widgetPath); + WidgetUpdateMode::Type CalcWidgetUpdatePolicy( + const OptionalWidgetVersion &existingVersion, + const OptionalWidgetVersion &incomingVersion) const; + void displayWidgetInfo(); + + public: + /** + * @brief Automaticaly sets installation process + */ + JobWidgetInstall(std::string const & widgetPath, + const WidgetInstallationStruct &installerStruct); + + DPL::Optional<WidgetHandle> getNewWidgetHandle() const; + bool getUnzipStartedFlag() const; + bool getUnzipFinishedFlag() const; + + //overrides + void SendProgress(); + void SendFinishedSuccess(); + void SendFinishedFailure(); + void SaveExceptionData(const Jobs::JobExceptionBase&); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif // WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_ diff --git a/src/jobs/widget_install/languages.def b/src/jobs/widget_install/languages.def new file mode 100644 index 0000000..e26443f --- /dev/null +++ b/src/jobs/widget_install/languages.def @@ -0,0 +1,15 @@ +ADD(de, de_DE) +ADD(el, el_GR) +ADD(en, en_US) +ADD(es, es_ES) +ADD(fr, fr_FR) +ADD(it, it_IT) +ADD(ja, ja_JP) +ADD(ko, ko_KR) +ADD(nl, nl_NL) +ADD(pt, pt_PT) +ADD(ru, ru_RU) +ADD(tr, tr_TR) +ADD(zh, zh_CN) +ADD(zh, zh_HK) +ADD(zh, zh_TW) diff --git a/src/jobs/widget_install/task_ace_check.cpp b/src/jobs/widget_install/task_ace_check.cpp new file mode 100644 index 0000000..ed87a98 --- /dev/null +++ b/src/jobs/widget_install/task_ace_check.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_ace_check.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task ace check + */ + +#include <widget_install/task_ace_check.h> +#include <dpl/assert.h> + +#include <widget_install/widget_install_context.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/job_widget_install.h> +#include <security_controller.h> + +#include <dpl/ace/PolicyResult.h> +#include <dpl/ace/Request.h> + +namespace Jobs { +namespace WidgetInstall { +TaskAceCheck::TaskAceCheck(InstallerContext& context) : + DPL::TaskDecl<TaskAceCheck>(this), + m_context(context) +{ + AddStep(&TaskAceCheck::StepPrepareForAce); + AddStep(&TaskAceCheck::StepAceCheck); + AddStep(&TaskAceCheck::StepProcessAceResponse); + AddStep(&TaskAceCheck::StepCheckAceResponse); +} + +void TaskAceCheck::StepPrepareForAce() +{ + Assert(!!m_context.widgetHandle); + m_context.featureLogic = + FeatureLogicPtr(new FeatureLogic(*m_context.widgetHandle)); +} + +void TaskAceCheck::StepAceCheck() +{ + + LogInfo("StepAceCheck!"); + // This widget does not use any device cap + if (m_context.featureLogic->isDone()) { + return; + } + + LogInfo("StepAceCheck!"); + DPL::String deviceCap = m_context.featureLogic->getDevice(); + + LogInfo("StepAceCheck!"); + + Assert(!!m_context.widgetHandle); + Request *request = new Request(*m_context.widgetHandle, + WidgetExecutionPhase_WidgetInstall); + request->addDeviceCapability(DPL::ToUTF8String(deviceCap)); + + CONTROLLER_POST_EVENT( + SecurityController, + SecurityControllerEvents::AuthorizeWidgetInstallEvent( + request, + makeICDelegate(&TaskAceCheck::ProcessAceResponse))); + + // PorcessAceResponse will Resume me. + m_context.job->Pause(); +} + +void TaskAceCheck::StepProcessAceResponse() +{ + LogInfo("StepProcessAceResponse"); + m_context.featureLogic->next(); + + // No device caps left to process + if (m_context.featureLogic->isDone()) { + LogInfo("All responses has been received from ACE."); + return; + } + + LogInfo("Next device cap."); + // Process next device cap + SwitchToStep(&TaskAceCheck::StepAceCheck); +} + +void TaskAceCheck::StepCheckAceResponse() +{ + LogInfo("Checking ACE response"); + if (m_context.featureLogic->isRejected()) { + LogDebug("Installation failure. Some devCap was not accepted by ACE."); + ThrowMsg(Exceptions::NotAllowed, "Instalation failure. " + "Some deviceCap was not accepted by ACE."); + } + LogInfo("Installation continues..."); +} + +void TaskAceCheck::ProcessAceResponse(PolicyResult policyResult) +{ + LogInfo("Received ACE response."); + + DPL::String deviceCap = m_context.featureLogic->getDevice(); + + if (policyResult == PolicyEffect::PERMIT) + m_context.staticPermittedDevCaps.insert(deviceCap); + + m_context.featureLogic->setAceResponse(policyResult != PolicyEffect::DENY); + m_context.job->Resume(); +} + +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_ace_check.h b/src/jobs/widget_install/task_ace_check.h new file mode 100644 index 0000000..4f9a110 --- /dev/null +++ b/src/jobs/widget_install/task_ace_check.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_ace_check.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief Header file for installer task ace check + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_ACE_CHECK_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_ACE_CHECK_H + +#include <dpl/task.h> +#include <dpl/event/inter_context_delegate.h> +#include <dpl/ace/PolicyResult.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskAceCheck : + public DPL::TaskDecl<TaskAceCheck>, + public DPL::Event::ICDelegateSupport<TaskAceCheck> +{ + private: + InstallerContext& m_context; + + void StepPrepareForAce(); + void StepAceCheck(); + void StepProcessAceResponse(); + void StepCheckAceResponse(); + void ProcessAceResponse(PolicyResult result); + + public: + TaskAceCheck(InstallerContext& context); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_ACE_CHECK_H */ diff --git a/src/jobs/widget_install/task_certify.cpp b/src/jobs/widget_install/task_certify.cpp new file mode 100644 index 0000000..d801066 --- /dev/null +++ b/src/jobs/widget_install/task_certify.cpp @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_certify.cpp + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +//SYSTEM INCLUDES +#include <cstring> +#include <string> +#include <dpl/assert.h> +#include <dpl/event/nested_loop.h> +#include <appcore-common.h> //TODO is it necessary here? +#include <pcrecpp.h> + +//WRT INCLUDES +#include <widget_install/task_certify.h> +#include <widget_install/job_widget_install.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <dpl/log/log.h> +#include <wrt_error.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include "wac_widget_id.h" + +#include <vcore/SignatureReader.h> +#include <vcore/SignatureFinder.h> +#include <vcore/SignatureValidator.h> +#include <vcore/DeveloperModeValidator.h> +#include <dpl/utils/wrt_global_settings.h> +#include <dpl/wrt-dao-ro/global_dao_read_only.h> + +using namespace ValidationCore; +using namespace WrtDB; + +namespace { +enum ButtonId +{ + BUTTON_ID_INSTALL, + BUTTON_ID_RESIGN +}; + +const std::string LABEL_NEW_LINE = "<br>"; +const std::string LABEL_NEW_LINE_2 = "<br><br>"; + +WidgetCertificateData toWidgetCertificateData(const SignatureData &data, + bool root) +{ + WidgetCertificateData result; + + result.chainId = data.getSignatureNumber(); + + result.owner = data.isAuthorSignature() ? + WidgetCertificateData::AUTHOR : WidgetCertificateData::DISTRIBUTOR; + + result.type = root ? + WidgetCertificateData::ROOT : WidgetCertificateData::ENDENTITY; + + CertificatePtr certificate; + + if (root) { + certificate = data.getRootCaCertificatePtr(); + } else { + certificate = data.getEndEntityCertificatePtr(); + } + + Assert(!certificate->getCommonName().IsNull() && "CommonName is Null"); + + result.strCommonName = *certificate->getCommonName(); + + result.strMD5Fingerprint = std::string("md5 ") + + SignatureValidator::FingerprintToColonHex( + certificate->getFingerprint(Certificate::FINGERPRINT_MD5)); + + result.strSHA1Fingerprint = std::string("sha-1 ") + + SignatureValidator::FingerprintToColonHex( + certificate->getFingerprint(Certificate::FINGERPRINT_SHA1)); + + return result; +} +} // namespace anonymous + +namespace Jobs { +namespace WidgetInstall { +TaskCertify::TaskCertify(InstallerContext &inCont) : + DPL::TaskDecl<TaskCertify>(this), + m_contextData(inCont), + m_cancelInstallation(false), + m_userAgreedToInstallUntrustedWidget(false) +{ + AddStep(&TaskCertify::stepSignature); + AddStep(&TaskCertify::stepWarningPopup); + AddStep(&TaskCertify::stepWarningPopupAnswer); + AddStep(&TaskCertify::stepAuthorInfoPopup); + AddStep(&TaskCertify::stepAuthorInfoPopupAnswer); + AddStep(&TaskCertify::stepFinalize); +} + +TaskCertify::~TaskCertify() +{ +} + +void TaskCertify::processDistributorSignature(const SignatureData &data, + bool first) +{ + // this signature is verified - + // no point in check domain WAC_ROOT and WAC_RECOGNIZED + m_contextData.wacSecurity.setDistributorSigned(true); + + if (data.getStorageType().contains(CertStoreId::WAC_ROOT)) { + m_contextData.wacSecurity.setWacSigned(true); + } + + CertificateCollection collection; + collection.load(data.getCertList()); + collection.sort(); + Assert(collection.isChain() && + "Certificate collection is not able to create chain. " + "It is not possible to verify this signature."); + + m_contextData.wacSecurity.getCertificateChainListRef().push_back( + collection); + + if (first) { + m_contextData.wacSecurity.getCertificateListRef().push_back( + toWidgetCertificateData(data, true)); + m_contextData.wacSecurity.getCertificateListRef().push_back( + toWidgetCertificateData(data, false)); + } +} + +void TaskCertify::processAuthorSignature(const SignatureData &data) +{ + using namespace ValidationCore; + LogInfo("DNS Identity match!"); + // this signature is verified or widget is distributor signed + m_contextData.wacSecurity.getAuthorCertificatePtr() = + data.getEndEntityCertificatePtr(); + m_contextData.wacSecurity.getCertificateListRef().push_back( + toWidgetCertificateData(data, true)); + m_contextData.wacSecurity.getCertificateListRef().push_back( + toWidgetCertificateData(data, false)); + + // match widget_id with one from dns identity set + WacWidgetId widgetId(m_contextData.widgetConfig.configInfo.widget_id); + + Certificate::AltNameSet dnsIdentity = + data.getEndEntityCertificatePtr()->getAlternativeNameDNS(); + + FOREACH(it, dnsIdentity){ + if (widgetId.matchHost(*it)) { + m_contextData.wacSecurity.setRecognized(true); + return; + } + } +} + +void TaskCertify::stepSignature() +{ + Assert(!m_contextData.tempWidgetPath.empty()); + + std::string widgetPath = m_contextData.tempWidgetPath + "/"; + + SignatureFileInfoSet signatureFiles; + SignatureFinder signatureFinder(widgetPath); + if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) { + LogError("Error in Signature Finder"); + ThrowMsg(Exceptions::InvalidPackage, + "Error openig temporary widget directory"); + } + + SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin(); + LogInfo("No of signatures: " << signatureFiles.size()); + + bool firstDistributorSignature = true; + bool testCertificate = false; + + bool complianceMode = GlobalDAOReadOnly::getComplianceMode(); + + for (; iter != signatureFiles.rend(); ++iter) { + LogInfo("Checking signature with id=" << iter->getFileNumber()); + SignatureData data(widgetPath + iter->getFileName(), + iter->getFileNumber()); + + Try { + SignatureReader xml; + xml.initialize(data, GlobalConfig::GetSignatureXmlSchema()); + xml.read(data); + SignatureValidator validator(GlobalConfig::IsOCSPEnabled(), + GlobalConfig::IsCRLEnabled(), + complianceMode); + SignatureValidator::Result result = + validator.check(data, widgetPath); + + if (result == SignatureValidator::SIGNATURE_REVOKED) { + LogWarning("Certificate is REVOKED"); + ThrowMsg(Exceptions::InvalidPackage, + "Certificate is REVOKED"); + } + + if (result == SignatureValidator::SIGNATURE_INVALID) { + LogWarning("Signature is INVALID"); + // TODO change exception name + ThrowMsg(Exceptions::InvalidPackage, + "Invalid Package"); + } + + if (data.isAuthorSignature()) { + if (result == SignatureValidator::SIGNATURE_VERIFIED || + m_contextData.wacSecurity.isDistributorSigned()) + { + processAuthorSignature(data); + } else if (result == SignatureValidator::SIGNATURE_DISREGARD) { + continue; + } + } else { + if (result == SignatureValidator::SIGNATURE_DISREGARD) { + continue; + } + // now signature _must_ be verified + processDistributorSignature(data, firstDistributorSignature); + firstDistributorSignature = false; + } + + DeveloperModeValidator developerModeValidator( + complianceMode, + GlobalDAOReadOnly::getComplianceFakeImei(), + GlobalDAOReadOnly::getComplianceFakeMeid()); + + developerModeValidator.check(data); + + testCertificate |= + data.getStorageType().contains(CertStoreId::DEVELOPER); + + bool developerMode = GlobalDAOReadOnly::GetDeveloperMode(); + + if (testCertificate && !developerMode) { + LogDebug("Widget signed by test certificate, " + "but developer mode is off."); + ThrowMsg(Exceptions::InvalidPackage, + "Widget signed by test certificate, " + "but developer mode is off."); + } + m_contextData.widgetConfig.isTestWidget = testCertificate; + } Catch(ParserSchemaException::Base) { + LogDebug("Error occured in ParserSchema."); + ReThrowMsg(Exceptions::InvalidPackage, + "Error occured in ParserSchema."); + } + Catch(DeveloperModeValidator::Exception::Base) { + LogDebug("Cannot validate developer certificate."); + ReThrowMsg(Exceptions::InvalidPackage, + "Cannot validate developer certificate."); + } + } + + if (signatureFiles.empty()) { + LogInfo("No signature files has been found."); + } + + LogInfo("================ Step: <<CSignature>> DONE ================"); +} + +void TaskCertify::stepWarningPopup() +{ + LogInfo("Step:: <<Warning Popup>>"); + // SP-2151: If widget is not recognized (OCSP status of any of certificates + // it is signed with is not recognized) WRT must notify user that + // widget cannot be installed as a trusted application, and let the + // user decide whether it should be installed as an untrusted + // application. + if (!m_contextData.wacSecurity.isDistributorSigned()) { + if (GlobalSettings::GetPopupsEnabledFlag()) { + m_contextData.job->Pause(); + std::string label = _("IDS_IM_POP_WIDGET_UNTRUSTED_WARNING") + + LABEL_NEW_LINE + + _("IDS_IM_WIDGET_WANT_TO_INSTALL"); + using namespace DPL::Popup; + CtrlPopupPtr popup = + PopupControllerSingleton::Instance().CreatePopup(); + popup->SetTitle(_("IDS_IM_POP_WIDGET_UNTRUSTED_TITLE")); + popup->Append(new PopupObject::Label(label)); + popup->Append(new PopupObject::Button(_("IDS_IM_BUTTON_INSTALL"), + BUTTON_ID_INSTALL)); + popup->Append(new PopupObject::Button(_("IDS_IM_BUTTON_RESIGN"), + BUTTON_ID_RESIGN)); + + ListenForAnswer(popup); + + PopupAnswerCallback cb = MakeAnswerCallback(this, + &TaskCertify::onWarningPopupAnswer); + + ShowPopupEvent event(popup, cb, DPL::Event::UNDEFINED_LOOP_HANDLE); + CONTROLLER_POST_EVENT(PopupController, event); + } else { + m_userAgreedToInstallUntrustedWidget = true; + } + } +} + +void TaskCertify::stepWarningPopupAnswer() +{ + LogInfo("Step: <<Warning Popup Answer>>"); + if (false == m_contextData.wacSecurity.isDistributorSigned() && + false == m_userAgreedToInstallUntrustedWidget) + { + LogWarning("User does not agreed to install unsigned widgets!"); + ThrowMsg(Exceptions::NotAllowed, "Widget not allowed"); + } +} + +void TaskCertify::stepAuthorInfoPopupAnswer() +{ + LogInfo("Step: <<Author Info Popup Answer>>"); + if (m_cancelInstallation) { + LogWarning("User does not agreed to install widget!"); + ThrowMsg(Exceptions::NotAllowed, "Widget not allowed"); + } +} + +std::string TaskCertify::createAuthorWidgetInfo() const +{ + std::string authorInfo; + if (m_contextData.wacSecurity.isRecognized()) { + authorInfo += _("IDS_IM_WIDGET_RECOGNISED"); + } else { + authorInfo += _("IDS_IM_WIDGET_UNRECOGNISED"); + } + + authorInfo += LABEL_NEW_LINE_2; + ValidationCore::CertificatePtr authorCert = + m_contextData.wacSecurity.getAuthorCertificatePtr(); + if (!!authorCert) { + DPL::Optional < DPL::String > organizationName = + authorCert->getOrganizationName(); + + authorInfo += _("IDS_IM_WIDGET_AUTHOR_ORGANIZATION_NAME"); + authorInfo += LABEL_NEW_LINE; + + if (!organizationName.IsNull()) { + authorInfo += DPL::ToUTF8String(*organizationName); + } else { + authorInfo += _("IDS_IM_WIDGET_ORGANIZATION_UNKNOWN"); + } + + authorInfo += LABEL_NEW_LINE_2; + + DPL::Optional < DPL::String > countryName = + authorCert->getCountryName(); + + authorInfo += _("IDS_IM_WIDGET_COUNTRY_NAME"); + authorInfo += LABEL_NEW_LINE; + + if (!countryName.IsNull()) { + authorInfo += DPL::ToUTF8String(*countryName); + } else { + authorInfo += _("IDS_IM_WIDGET_COUNTRY_UNKNOWN"); + } + } else { + authorInfo += + _("IDS_IM_WIDGET_DOES_NOT_CONTAIN_RECOGNIZED_AUTHOR_SIGNATURE"); + } + return authorInfo; +} + +void TaskCertify::stepAuthorInfoPopup() +{ + LogInfo("Step:: <<Author Popup Information>>"); + + if (!GlobalSettings::GetPopupsEnabledFlag()) { + LogDebug("Popups are not enabled! Author information wont be shown."); + return; + } + + using namespace DPL::Popup; + m_contextData.job->Pause(); + std::string label = createAuthorWidgetInfo() + LABEL_NEW_LINE + _("IDS_IM_WIDGET_WANT_TO_INSTALL"); + + CtrlPopupPtr popup = PopupControllerSingleton::Instance().CreatePopup(); + popup->SetTitle(_("IDS_IM_WIDGET_HEAD")); + popup->Append(new PopupObject::Label(label)); + popup->Append(new PopupObject::Button(_("IDS_IM_BUTTON_INSTALL"), + BUTTON_ID_INSTALL)); + popup->Append(new PopupObject::Button(_("IDS_IM_BUTTON_RESIGN"), + BUTTON_ID_RESIGN)); + ListenForAnswer(popup); + ShowPopupEvent event(popup, + MakeAnswerCallback( + this, + &TaskCertify::onAuthorInfoPopupAnswer), + DPL::Event::UNDEFINED_LOOP_HANDLE); + CONTROLLER_POST_EVENT(PopupController, event); +} + +void TaskCertify::stepFinalize() +{ + LogInfo("Step: <<CERTYFYING DONE>>"); +} + +void TaskCertify::onWarningPopupAnswer(const DPL::Popup::AnswerCallbackData& answer) +{ + m_contextData.job->Resume(); + if (BUTTON_ID_RESIGN == answer.buttonAnswer) { + m_userAgreedToInstallUntrustedWidget = false; + } else if (BUTTON_ID_INSTALL == answer.buttonAnswer) { + m_userAgreedToInstallUntrustedWidget = true; + } else { + Assert(false && "Unpredicted answer received."); + } +} + +void TaskCertify::onAuthorInfoPopupAnswer( + const DPL::Popup::AnswerCallbackData& answer) +{ + m_contextData.job->Resume(); + if (BUTTON_ID_RESIGN == answer.buttonAnswer) { + m_cancelInstallation = true; + } +} +} //namespace WidgetInstall +} //namespace Jobs + diff --git a/src/jobs/widget_install/task_certify.h b/src/jobs/widget_install/task_certify.h new file mode 100644 index 0000000..dbd99bf --- /dev/null +++ b/src/jobs/widget_install/task_certify.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_certify.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_H + +//SYSTEM INCLUDES +#include <string> +#include <libxml/c14n.h> + +//WRT INCLUDES +#include <dpl/task.h> +#include <dpl/popup/popup_controller.h> + +class InstallerContext; + +namespace ValidationCore { +class SignatureData; +} + +namespace Jobs { +namespace WidgetInstall { +class TaskCertify : + public DPL::TaskDecl<TaskCertify>, + public DPL::Popup::PopupControllerUser +{ + public: + TaskCertify(InstallerContext &inCont); + virtual ~TaskCertify(); + + private: + //data + InstallerContext& m_contextData; + bool m_cancelInstallation; + bool m_userAgreedToInstallUntrustedWidget; + + //steps + void stepSignature(); + void stepWarningPopup(); + void stepWarningPopupAnswer(); + void stepAuthorInfoPopup(); + void stepAuthorInfoPopupAnswer(); + void stepFinalize(); + + void processDistributorSignature(const ValidationCore::SignatureData &data, + bool first); + void processAuthorSignature(const ValidationCore::SignatureData &data); + + std::string createAuthorWidgetInfo() const; + + void onWarningPopupAnswer(const DPL::Popup::AnswerCallbackData &answer); + void onAuthorInfoPopupAnswer(const DPL::Popup::AnswerCallbackData &answer); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_H diff --git a/src/jobs/widget_install/task_db_update.cpp b/src/jobs/widget_install/task_db_update.cpp new file mode 100644 index 0000000..0d087c9 --- /dev/null +++ b/src/jobs/widget_install/task_db_update.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_db_update.cpp + * @author Lukasz Wrzosek(l.wrzosek@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task database updating + */ +#include <time.h> +#include <sys/stat.h> +#include <widget_install/task_db_update.h> +#include <widget_install/job_widget_install.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <dpl/wrt-dao-ro/config_parser_data.h> +#include <dpl/utils/wrt_utility.h> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <dpl/ace-dao-rw/AceDAO.h> +#include <string> +#include <dpl/assert.h> +#include <dpl/wrt-dao-ro/global_config.h> +//#include <widget_controller.h> +#include <Ecore_File.h> +#include <sstream> +#include <dpl/localization/localization_utils.h> + +using namespace LocalizationUtils; +using namespace WrtDB; + +namespace Jobs { +namespace WidgetInstall { +TaskDbUpdate::TaskDbUpdate(InstallerContext& context) : + DPL::TaskDecl<TaskDbUpdate>(this), + m_context(context) +{ + AddStep(&TaskDbUpdate::StepDbUpdate); + AddStep(&TaskDbUpdate::StepSetPkgName); + AddStep(&TaskDbUpdate::StepCreateDirs); + AddStep(&TaskDbUpdate::StepRenamePath); + + + AddAbortStep(&TaskDbUpdate::StepAbortDBUpdate); + AddAbortStep(&TaskDbUpdate::StepAbortRenamePath); +} + +void TaskDbUpdate::StepSetPkgName() +{ + // We shoud send to backend installer widget id and package name of + // installed widget so that backend installer can send two information + // to menuscreen. This work is needed for menuscreen to update installation + // of widget normally from samsung appstore client. + Assert(!!m_context.widgetHandle && "Widget Handle should be initialized"); + std::string l_pkgname; + + if (!!m_context.widgetConfig.pkgname) { + l_pkgname = + DPL::ToUTF8String(*m_context.widgetConfig.pkgname); + } else { + LogInfo("package name is generated by WRT"); + std::ostringstream pkgname_stream; + + pkgname_stream << WrtDB::GlobalConfig::GetPkgnamePrefix() << + *m_context.widgetHandle; + + DPL::String pkgname = DPL::FromUTF8String(pkgname_stream.str()); + m_context.widgetConfig.pkgname = pkgname; + l_pkgname = pkgname_stream.str(); + } + + + LogInfo("package name : " << l_pkgname); + LogInfo("GUID : " << m_context.widgetConfig.guid); + + WrtDB::WidgetDAO widgetDao(*m_context.widgetHandle); + widgetDao.setPkgName(m_context.widgetConfig.pkgname); +} + + +void TaskDbUpdate::StepCreateDirs() +{ + std::ostringstream widgetPath; + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + if (pkgname.IsNull()) { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + widgetPath << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + widgetPath << pkgname << "/"; + + std::string widgetBinPath = widgetPath.str(); + std::string widgetIconPath = widgetPath.str(); + std::string widgetSrcPath = widgetPath.str(); + + _WrtMakeDir(widgetPath.str().c_str(), 0755, WRT_FILEUTILS_RECUR); + + widgetBinPath += GlobalConfig::GetUserWidgetExecPath(); + _WrtMakeDir(widgetBinPath.c_str(), 0755, WRT_FILEUTILS_RECUR); + + widgetIconPath += GlobalConfig::GetUserWidgetDesktopIconPath(); + _WrtMakeDir(widgetIconPath.c_str(), 0755, WRT_FILEUTILS_RECUR); + + widgetSrcPath += GlobalConfig::GetWidgetSrcPath(); + _WrtMakeDir(widgetSrcPath.c_str(), 0755, WRT_FILEUTILS_RECUR); +} + +void TaskDbUpdate::StepDbUpdate() +{ + Try + { + // If there is existing model, remove its database data + if (true == m_context.existingWidgetInfo.isExist) { + WidgetHandle old = m_context.existingWidgetInfo.existingHandle; + LogInfo("Unregistering widget...: " << old); + WidgetDAO::unregisterWidget(old); + LogInfo("Widget unregistered"); + } + + /* Set install Time */ + time(&m_context.widgetConfig.installedTime); + + LogInfo("Registering widget..."); + + m_context.widgetHandle = WidgetDAO::registerWidget( + m_context.widgetConfig, + m_context.wacSecurity, + GetUserAgentLanguageTags()); + + AceDB::AceDAO::setStaticDevCapPermissions( + *(m_context.widgetHandle), + m_context.staticPermittedDevCaps); + + LogInfo("Widget registered"); + } + Catch(WidgetDAO::Exception::DatabaseError) + { + LogWarning("Database failure!"); + ReThrowMsg(Exceptions::DatabaseFailure, "Database failure!"); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + LogDebug("Database failure!"); + ReThrowMsg(Exceptions::DatabaseFailure, "Database failure!"); + } + + m_context.job->UpdateProgress( + InstallerContext::INSTALL_DB_UPDATE, + "Widget DB UPDATE Finished"); +} + +void TaskDbUpdate::StepRenamePath() +{ + std::ostringstream instDir; + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + if (pkgname.IsNull()) { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + instDir << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + instDir << pkgname << "/"; + instDir << GlobalConfig::GetWidgetSrcPath(); + + LogDebug("Copy file from temp directory to " << instDir.str()); + if (!_WrtUtilRemoveDir(instDir.str().c_str())) { + _WrtUtilChangeDir(GlobalConfig::GetUserInstalledWidgetPath()); + ThrowMsg(Exceptions::RemovingFolderFailure, + "Error occurs during removing existing folder"); + } + + if (rename(m_context.tempWidgetPath.c_str(), instDir.str().c_str()) < 0) { + ThrowMsg(Exceptions::UnknownError, + "Error occurs during renaming widget folder"); + } + + m_context.job->UpdateProgress( + InstallerContext::INSTALL_RENAME_PATH, + "Widget Rename path Finished"); +} + +void TaskDbUpdate::StepAbortDBUpdate() +{ + LogWarning("[DB Update Task] Aborting... (DB Clean)"); + Assert(!!m_context.widgetHandle); + Try + { + WidgetDAO::unregisterWidget(*m_context.widgetHandle); + + LogDebug("Cleaning DB successful!"); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + //TODO What should happen here? + LogError("Failed to handle StepAbortDBClean!"); + // ReThrowMsg(Exceptions::DbStepFailed, "Failed to handle StepAbortDBClean!"); + } +} + +void TaskDbUpdate::StepAbortRenamePath() +{ + Assert(!!m_context.widgetHandle); + std::ostringstream widgetPath; + widgetPath << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + widgetPath << *m_context.widgetHandle; + + struct stat fileInfo; + if (stat(widgetPath.str().c_str(), &fileInfo) != 0) { + return; + } + + if (rename(widgetPath.str().c_str(), + m_context.tempWidgetPath.c_str()) < 0) { + LogError("Failed to rename"); + //Ignoring failures in Abort + } +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_db_update.h b/src/jobs/widget_install/task_db_update.h new file mode 100644 index 0000000..6097e35 --- /dev/null +++ b/src/jobs/widget_install/task_db_update.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_db_update.h + * @author Lukasz Wrzosek(l.wrzosek@samsung.com) + * @version 1.0 + * @brief Header file for installer task database updating + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DB_UPDATE_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DB_UPDATE_H + +#include <dpl/task.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskDbUpdate : + public DPL::TaskDecl<TaskDbUpdate> +{ + private: + InstallerContext& m_context; + + void StepCreateDirs(); + void StepDbUpdate(); + void StepRenamePath(); + + void StepAbortDBUpdate(); + void StepAbortRenamePath(); + + void StepSetPkgName(); + + public: + TaskDbUpdate(InstallerContext& context); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DB_UPDATE_H diff --git a/src/jobs/widget_install/task_desktop_file.cpp b/src/jobs/widget_install/task_desktop_file.cpp new file mode 100644 index 0000000..c0a7b6b --- /dev/null +++ b/src/jobs/widget_install/task_desktop_file.cpp @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_desktop_file.cpp + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +//SYSTEM INCLUDES +#include <string> +#include <dpl/assert.h> + +//WRT INCLUDES +#include <widget_install/task_desktop_file.h> +#include <widget_install/job_widget_install.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <dpl/log/log.h> +#include <dpl/file_input.h> +#include <dpl/file_output.h> +#include <dpl/copy.h> +#include <dpl/exception.h> +#include <dpl/foreach.h> +#include <dpl/sstream.h> +#include <dpl/string.h> +#include <dpl/optional.h> +#include <map> + +using namespace WrtDB; + +namespace { +typedef std::map<DPL::String, DPL::String> LanguageTagMap; + +LanguageTagMap getLanguageTagMap() +{ + LanguageTagMap map; + +#define ADD(tag, l_tag) map.insert(std::make_pair(L ## # tag, L ## # l_tag)); +#include "languages.def" +#undef ADD + + return map; +} + +DPL::OptionalString getLangTag(const DPL::String& tag) +{ + static LanguageTagMap TagsMap = + getLanguageTagMap(); + + DPL::String langTag = tag; + + LogDebug("Trying to map language tag: " << langTag); + size_t pos = langTag.find_first_of(L'_'); + if (pos != DPL::String::npos) { + langTag.erase(pos); + } + DPL::OptionalString ret; + + LanguageTagMap::iterator it = TagsMap.find(langTag); + if (it != TagsMap.end()) { + ret = it->second; + } + LogDebug("Mapping IANA Language tag to language tag: " << + langTag << " -> " << ret); + + return ret; +} +} + +namespace Jobs { +namespace WidgetInstall { +TaskDesktopFile::TaskDesktopFile(InstallerContext &inCont) : + DPL::TaskDecl<TaskDesktopFile>(this), + m_context(inCont) +{ + AddStep(&TaskDesktopFile::stepCopyIconFiles); + AddStep(&TaskDesktopFile::stepCreateDesktopFile); + AddStep(&TaskDesktopFile::stepCreateExecFile); + AddStep(&TaskDesktopFile::stepFinalize); +} + +TaskDesktopFile::~TaskDesktopFile() +{ +} + +void TaskDesktopFile::stepCreateDesktopFile() +{ + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + desktop_name << pkgname << ".desktop"; + desktop_file << "/tmp/" << desktop_name.str(); + LogInfo("desktop file : " << desktop_file.str()); + std::ofstream file(desktop_file.str().c_str()); + + saveWidgetType(file); + saveWidgetExecPath(file); + saveWidgetName(file); + saveWidgetIcons(file); + saveWidgetVersion(file); + saveWidgetOtherInfo(file); + saveAppServiceInfo(file); + + file.close(); + + moveDesktopFile(); + + m_context.job->UpdateProgress( + InstallerContext::INSTALL_CREATE_DESKTOP, + "Widget Desktop Creation Finished"); +} + +void TaskDesktopFile::stepCreateExecFile() +{ + //ln -s /usr/bin/wrt-client {widget-handle} + + std::ostringstream real_path; + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + if (pkgname.IsNull()) { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + real_path << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + real_path << pkgname << "/"; + real_path << GlobalConfig::GetUserWidgetExecPath() << "/" << + m_context.widgetHandle; + std::string wrt_client = GlobalConfig::GetWrtClientExec(); + + LogInfo("link -s " << wrt_client << " " << real_path.str()); + symlink(wrt_client.c_str(), real_path.str().c_str()); + + m_context.job->UpdateProgress( + InstallerContext::INSTALL_CREATE_EXECFILE, + "Widget execfile creation Finished"); +} + +void TaskDesktopFile::stepCopyIconFiles() +{ + LogDebug("CopyIconFiles"); + + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + if (pkgname.IsNull()) { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + Assert(!!m_context.widgetHandle); + WidgetDAO dao(*m_context.widgetHandle); + WidgetDAO::WidgetLocalizedIconList locList = dao.getLocalizedIconList(); + WidgetDAO::WidgetIconList list = dao.getIconList(); + FOREACH(it, locList) + { + DPL::String i = it->widgetLocale; + DPL::OptionalString src; + FOREACH(icon, list) + { + if (icon->iconId == it->iconId) { + src = icon->iconSrc; + } + } + LogDebug("Icon for locale: " << i << "is : " << src); + + std::ostringstream sourceFile; + std::ostringstream targetFile; + + if (!!src) { + sourceFile << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + sourceFile << pkgname << "/"; + sourceFile << GlobalConfig::GetWidgetSrcPath() << "/"; + + targetFile << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + targetFile << pkgname << "/"; + targetFile << GlobalConfig::GetUserWidgetDesktopIconPath() << "/"; + + if (!i.empty()) { + sourceFile << "locales/" << i << "/"; + } + sourceFile << *src; + targetFile << getIconTargetFilename(i); + + } else { + //Use WRT default (not from the widget) only if widget default (not + // localized) doesn't exist. + if (i.empty()) { + LogError("Using Default Icon for widget"); + sourceFile << GlobalConfig::GetUserWidgetDefaultIconFile(); + } else { + continue; + } + } + + LogDebug("Copying icon: " << sourceFile.str() << + " -> " << targetFile.str()); + + Try + { + DPL::FileInput input(sourceFile.str()); + DPL::FileOutput output(targetFile.str()); + DPL::Copy(&input, &output); + } + + Catch(DPL::FileInput::Exception::Base) + { + // Error while opening or closing source file + //ReThrowMsg(InstallerException::CopyIconFailed, sourceFile.str()); + LogError( + "Copying widget's icon failed. Widget's icon will not be"\ + "available from Main Screen"); + } + + Catch(DPL::FileOutput::Exception::Base) + { + // Error while opening or closing target file + //ReThrowMsg(InstallerException::CopyIconFailed, targetFile.str()); + LogError( + "Copying widget's icon failed. Widget's icon will not be"\ + "available from Main Screen"); + } + + Catch(DPL::CopyFailed) + { + // Error while copying + //ReThrowMsg(InstallerException::CopyIconFailed, targetFile.str()); + LogError( + "Copying widget's icon failed. Widget's icon will not be"\ + "available from Main Screen"); + } + } + + m_context.job->UpdateProgress( + InstallerContext::INSTALL_COPY_ICONFILE, + "Widget iconfile copy Finished"); +} + +void TaskDesktopFile::moveDesktopFile() +{ + std::ostringstream destFile; + destFile << GlobalConfig::GetUserWidgetDesktopPath() << "/"; + destFile << desktop_name.str(); + LogInfo("cp " << desktop_file.str() << " " << destFile.str()); + Try + { + DPL::FileInput input(desktop_file.str()); + DPL::FileOutput output(destFile.str()); + DPL::Copy(&input, &output); + } + + Catch(DPL::FileInput::Exception::Base) + { + // Error while opening or closing source file + // ReThrowMsg(InstallerException::CopyIconFailed, + // desktop_file.str()); + LogError( + "Creating Desktop File Failed. Widget's icon will not be available"\ + "from Main Screen"); + } + + Catch(DPL::FileOutput::Exception::Base) + { + // Error while opening or closing target file + // ReThrowMsg(InstallerException::CopyIconFailed, + // destFile.str()); + LogError( + "Creating Desktop File Failed. Widget's icon will not be available"\ + "from Main Screen"); + } + + Catch(DPL::CopyFailed) + { + // Error while copying + // ReThrowMsg(InstallerException::CopyIconFailed, + // destFile.str()); + LogError( + "Creating Desktop File Failed. Widget's icon will not be available"\ + "from Main Screen"); + } + + //removing temp file + unlink(desktop_file.str().c_str()); +} + +void TaskDesktopFile::saveWidgetType(std::ofstream &file) +{ + file << "Type=" << "Application" << std::endl; +} + +void TaskDesktopFile::saveWidgetExecPath(std::ofstream &file) +{ + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + if (pkgname.IsNull()) { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + file << "Exec="; + file << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + file << pkgname << "/"; + file << GlobalConfig::GetUserWidgetExecPath() << "/"; + file << m_context.widgetHandle << std::endl; +} + +void TaskDesktopFile::saveWidgetVersion(std::ofstream &file) +{ + DPL::OptionalString widget_version = m_context.widgetConfig.version; + file << "Version=" << widget_version << std::endl; +} + +void TaskDesktopFile::saveWidgetName(std::ofstream &file) +{ + Assert(!!m_context.widgetHandle); + WidgetDAO dao(*m_context.widgetHandle); + LanguageTagsList languageTags(dao.getLanguageTags()); + FOREACH(i, languageTags) + { + DPL::OptionalString tag = getLangTag(*i);// translate en -> en_US etc + if (tag.IsNull()) { tag = *i; } + + saveLocalizedKey(file, L"Name", *tag); + + DPL::OptionalString name = dao.getLocalizedInfo(*i).name; + if (!!name) { + file << *name; + } else { + file << "Widget " << *m_context.widgetHandle; + } + file << std::endl; + } +} + +void TaskDesktopFile::saveWidgetIcons(std::ofstream &file) +{ + //TODO this file will need to be updated when user locale preferences + //changes. + Assert(!!m_context.widgetHandle); + WidgetDAO dao(*m_context.widgetHandle); + + WidgetDAO::WidgetLocalizedIconList locList = dao.getLocalizedIconList(); + WidgetDAO::WidgetIconList list = dao.getIconList(); + + LanguageTagsList languageTags(dao.getLanguageTags()); + FOREACH(it, locList) + { + DPL::String i = it->widgetLocale; + DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc + if (tag.IsNull()) { tag = i; } + + saveLocalizedKey(file, L"Icon", *tag); + + DPL::OptionalString src; + FOREACH(icon, list) + { + if (icon->iconId == it->iconId) { + src = icon->iconSrc; + } + } + if (!!src) { + //If menuscreen need use absolute path of widget's icon, comment out + //the following lines. + //file << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + //file << WRT_WIDGET_PKGNAME_PREFIX << m_context.widgetHandle + // << "/"; + //file << GlobalConfig::GetUserWidgetDesktopIconPath() << "/"; + file << getIconTargetFilename(i) << std::endl; + } + } +} + +DPL::String TaskDesktopFile::getIconTargetFilename( + const DPL::String& languageTag) const +{ + DPL::OStringStream filename; + DPL::Optional<DPL::String> pkgname = m_context.widgetConfig.pkgname; + if (pkgname.IsNull()) { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + filename << DPL::ToUTF8String(*pkgname).c_str(); + + if (!languageTag.empty()) { + DPL::OptionalString tag = getLangTag(languageTag); // translate en -> en_US etc + if (tag.IsNull()) { tag = languageTag; } + DPL::String locale = + LocalizationUtils::BCP47LanguageTagToLocale(*tag); + + if(locale.empty()) { + filename << L"." << languageTag; + } else { + filename << L"." << locale; + } + } + + filename << L".png"; + return filename.str(); +} + +void TaskDesktopFile::saveWidgetOtherInfo(std::ofstream &file) +{ + DPL::Optional<DPL::String> widgetID = m_context.widgetConfig.guid; + + // /* network */ + // strncat(desktop, format_network, strlen(format_network)); + // //TODO -- get the network value from the widget + // strncat(desktop, "True", 4); + // strncat(desktop, line, strlen(line)); + + /* Comment */ + file << "Comment=Widget application" << std::endl; + + /* bg_schedule */ + //file << "BG_SCHEDULE=True" << std::endl; + + /* visible */ + file << "Visible=True" << std::endl; + + file << "X-SLP-BaseLayoutWidth=720" << std::endl; + file << "X-SLP-BaseLayoutHeight=1280" << std::endl; + file << "X-SLP-IsHorizontalScale=True" << std::endl; + file << "X-SLP-PackageType=wgt" << std::endl; + if (!widgetID.IsNull()) { + file << "X-SLP-PackageID=" << DPL::ToUTF8String(*widgetID).c_str() << std::endl; + } +} + +void TaskDesktopFile::saveAppServiceInfo(std::ofstream &file) +{ + Assert(!!m_context.widgetHandle); + WidgetDAOReadOnly dao(*m_context.widgetHandle); + WidgetApplicationServiceList appServiceList; + dao.getAppServiceList(appServiceList); + + if (appServiceList.empty()) { + LogInfo("Widget doesn't contain application service"); + return; + } + + // X-SLP-SVC=operation:scheme:mime; + file << "X-SLP-SVC="; + FOREACH(it, appServiceList) { + file << DPL::ToUTF8String(it->operation).c_str() << ":"; + if (it->scheme.empty()) { + file << "NULL" << ":"; + } else { + file << DPL::ToUTF8String(it->scheme).c_str() << ":"; + } + if (it->mime.empty()) { + file << "NULL" << ";"; + } else { + file << DPL::ToUTF8String(it->mime).c_str() << ";"; + } + } +} + +void TaskDesktopFile::stepFinalize() +{ + LogInfo("Finished DesktopFile step"); +} + +void TaskDesktopFile::saveLocalizedKey(std::ofstream &file, + const DPL::String& key, + const DPL::String& languageTag) +{ + DPL::String locale = + LocalizationUtils::BCP47LanguageTagToLocale(languageTag); + + file << key; + if (!locale.empty()) { + file << "[" << locale << "]"; + } + file << "="; +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_desktop_file.h b/src/jobs/widget_install/task_desktop_file.h new file mode 100644 index 0000000..2218168 --- /dev/null +++ b/src/jobs/widget_install/task_desktop_file.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_desktop_file.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DESKTOP_FILE_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DESKTOP_FILE_H + +//SYSTEM INCLUDES +#include <fstream> + +//WRT INCLUDES +#include <dpl/task.h> +#include <dpl/localization/localization_utils.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskDesktopFile : + public DPL::TaskDecl<TaskDesktopFile> +{ + public: + TaskDesktopFile(InstallerContext &inCont); + virtual ~TaskDesktopFile(); + + private: + //context data + InstallerContext &m_context; + + //TODO stepAbort + //steps + void stepCreateDesktopFile(); + void stepCreateExecFile(); + void stepFinalize(); + void stepCopyIconFiles(); + + //private data + std::ostringstream desktop_name; + std::ostringstream desktop_file; + + //private methods + void moveDesktopFile(); + void saveWidgetType(std::ofstream &file); + void saveWidgetExecPath(std::ofstream &file); + void saveWidgetName(std::ofstream &file); + void saveWidgetIcons(std::ofstream &file); + void saveWidgetVersion(std::ofstream &file); + void saveWidgetOtherInfo(std::ofstream &file); + void saveAppServiceInfo(std::ofstream &file); + + static void saveLocalizedKey(std::ofstream &file, + const DPL::String& key, + const DPL::String& languageTag); + DPL::String getIconTargetFilename(const DPL::String& languageTag) const; +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DESKTOP_FILE_H */ diff --git a/src/jobs/widget_install/task_parental_mode.cpp b/src/jobs/widget_install/task_parental_mode.cpp new file mode 100644 index 0000000..aad45e0 --- /dev/null +++ b/src/jobs/widget_install/task_parental_mode.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_parental_mode.cpp + * @author Janusz Majnert (j.majnert@samsung.com) + * @version 1.0 + * @brief Implementation for parental mode check installer task + */ +#include <widget_install/task_parental_mode.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <dpl/log/log.h> + +namespace Jobs { +namespace WidgetInstall { +TaskParentalMode::TaskParentalMode(InstallerContext &installerContext) : + DPL::TaskDecl<TaskParentalMode>(this), + m_installerContext(installerContext) +{ + AddStep(&TaskParentalMode::StepCheckParentalMode); +} + +TaskParentalMode::~TaskParentalMode() +{ + //Nothing to do for now +} + +void TaskParentalMode::StepCheckParentalMode() +{ + LogInfo("Step: Checking parental mode status"); + + using namespace WrtDB; + if (GlobalDAOReadOnly::GetParentalMode()) { + Throw(Exceptions::ParentalModeActive); + } +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_parental_mode.h b/src/jobs/widget_install/task_parental_mode.h new file mode 100644 index 0000000..e3eeec5 --- /dev/null +++ b/src/jobs/widget_install/task_parental_mode.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_parental_mode.h + * @author Janusz Majnert (j.majnert@samsung.com) + * @version 1.0 + * @brief Implementation for parental mode check installer task + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PARENTAL_MODE_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PARENTAL_MODE_H + +#include <dpl/task.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskParentalMode : + public DPL::TaskDecl<TaskParentalMode> +{ + private: + // Installation context + InstallerContext &m_installerContext; + + // Steps + void StepCheckParentalMode(); + + public: + explicit TaskParentalMode(InstallerContext &installerContext); + virtual ~TaskParentalMode(); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PARENTAL_MODE_H diff --git a/src/jobs/widget_install/task_private_storage.cpp b/src/jobs/widget_install/task_private_storage.cpp new file mode 100644 index 0000000..f0216e7 --- /dev/null +++ b/src/jobs/widget_install/task_private_storage.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file installer_task_private_storage.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task private storage. + */ +#include "task_private_storage.h" + +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +#include <sys/types.h> +#include <unistd.h> +#include <string> + +#include <dpl/log/log.h> +#include <dpl/errno_string.h> + +#include <dpl/wrt-dao-ro/widget_config.h> +#include <dpl/utils/file_utils.h> +#include <widget_install/job_widget_install.h> +#include <widget_install/widget_install_context.h> +#include <widget_install/widget_install_errors.h> + +#define WEBAPP_DEFAULT_UID 5000 +#define WEBAPP_DEFAULT_GID 5000 + +namespace { +const mode_t PRIVATE_STORAGE_MODE = 0700; +} + +namespace Jobs { +namespace WidgetInstall { +TaskPrivateStorage::TaskPrivateStorage(InstallerContext& context) : + DPL::TaskDecl<TaskPrivateStorage>(this), + m_context(context) +{ + AddStep(&TaskPrivateStorage::StepCreateDirectory); +} + +void TaskPrivateStorage::StepCreateDirectory() +{ + using namespace WrtDB; + + LogInfo("Step: Creating private storage directory."); + + m_context.installStep = + InstallerContext::INSTALL_CREATE_PRIVATE_STORAGE; + + std::ostringstream widgetPath; + DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; + if(!pkgname.IsNull()) { + widgetPath << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + widgetPath << pkgname << "/"; + } else { + ThrowMsg(Exceptions::InternalError, "No Package name exists."); + } + + if (access(widgetPath.str().c_str(), W_OK | X_OK) != 0) { + ThrowMsg(Exceptions::InternalError, DPL::GetErrnoString()); + } + + std::ostringstream storagePath; + storagePath << widgetPath.str().c_str() + << GlobalConfig::GetWidgetPrivateStoragePath(); + + if (access(storagePath.str().c_str(), F_OK) != 0) { + FileUtils::MakePath(storagePath.str(), PRIVATE_STORAGE_MODE); + // '5000' is default uid, gid for applications. + // So installed applications should be launched as process of uid '5000'. + // the process can access private directory 'data' of itself. + if(chown(storagePath.str().c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Exceptions::InternalError, + "Chown to invaild user"); + } + } else if (access(storagePath.str().c_str(), W_OK | R_OK | X_OK) == 0) { + LogInfo("Private storage already exists."); + } else { + ThrowMsg(Exceptions::InternalError, + "No access to private storage."); + } + + m_context.job->UpdateProgress( + InstallerContext::INSTALL_CREATE_PRIVATE_STORAGE, + "Private storage created." + ); +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_private_storage.h b/src/jobs/widget_install/task_private_storage.h new file mode 100644 index 0000000..e919f6b --- /dev/null +++ b/src/jobs/widget_install/task_private_storage.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_private_storage.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @version 1.0 + * @brief Header file for installer task private storage. + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PRIVATESTORAGE_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PRIVATESTORAGE_H + +#include <dpl/task.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskPrivateStorage : public DPL::TaskDecl<TaskPrivateStorage> +{ + public: + explicit TaskPrivateStorage(InstallerContext& context); + + private: + void StepCreateDirectory(); + + private: + InstallerContext& m_context; +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif diff --git a/src/jobs/widget_install/task_smack.cpp b/src/jobs/widget_install/task_smack.cpp new file mode 100644 index 0000000..f8e679c --- /dev/null +++ b/src/jobs/widget_install/task_smack.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_smack.cpp + * @author Piotr Kozbial (p.kozbial@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task smack + */ + +#include <widget_install/task_smack.h> +#include <widget_install/widget_install_context.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/job_widget_install.h> +#include <dpl/foreach.h> +#ifdef WRT_SMACK_ENABLED +#include <privilege-control.h> +#endif + +#include <sstream> + +namespace Jobs { +namespace WidgetInstall { +TaskSmack::TaskSmack(InstallerContext& context) : + DPL::TaskDecl<TaskSmack>(this), + m_context(context) +{ + AddStep(&TaskSmack::Step); +} + +void TaskSmack::Step() +{ + LogInfo("----------------> SMACK: Jobs::WidgetInstall::TaskSmack::Step()"); +#ifdef WRT_SMACK_ENABLED + std::stringstream devcaps; + FOREACH(it, m_context.staticPermittedDevCaps) { + std::string utf8 = DPL::ToUTF8String(*it); + if (it != m_context.staticPermittedDevCaps.begin()) + devcaps << ","; + devcaps << utf8; + } + DPL::OptionalString pkgName = m_context.widgetConfig.Pkgname; + Assert(!pkgName.IsNull() && "widget doesn't have a pkg name"); + int result = handle_access_control_conf_forWAC( + DPL::ToUTF8String(*pkgName).c_str(), + devcaps.str().c_str(), + OPERATION_INSTALL); + Assert(result==PC_OPERATION_SUCCESS && "access control setup failed"); +#endif +} + +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_smack.h b/src/jobs/widget_install/task_smack.h new file mode 100644 index 0000000..e4ba39a --- /dev/null +++ b/src/jobs/widget_install/task_smack.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_smack.h + * @author Piotr Kozbial (p.kozbial@samsung.com) + * @version 1.0 + * @brief Header file for installer task smack + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_SMACK_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_SMACK_H + +#include <dpl/task.h> +#include <dpl/event/inter_context_delegate.h> +#include <dpl/ace/PolicyResult.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskSmack: + public DPL::TaskDecl<TaskSmack>, + public DPL::Event::ICDelegateSupport<TaskSmack> +{ + private: + InstallerContext& m_context; + + void Step(); + + public: + TaskSmack(InstallerContext& context); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_SMACK_H */ diff --git a/src/jobs/widget_install/task_unzip.cpp b/src/jobs/widget_install/task_unzip.cpp new file mode 100644 index 0000000..1da1176 --- /dev/null +++ b/src/jobs/widget_install/task_unzip.cpp @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_unzip.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task unzip + */ +#include <widget_install/task_unzip.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <dpl/log/log.h> +#include <dpl/copy.h> +#include <dpl/file_output.h> +#include <dpl/abstract_waitable_input_adapter.h> +#include <dpl/errno_string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <errno.h> +#include <ftw.h> +#include <dpl/utils/file_utils.h> + +using namespace WrtDB; + +namespace // anonymous +{ +const char * const TEMPORARY_PATH_POSTFIX = "temp"; +const mode_t TEMPORARY_PATH_MODE = 0775; + +struct PathAndFilePair +{ + std::string path; + std::string file; + + PathAndFilePair(const std::string &p, + const std::string &f) : + path(p), + file(f) + { + } +}; + +PathAndFilePair SplitFileAndPath(const std::string &filePath) +{ + std::string::size_type position = filePath.rfind('/'); + + // Is this only a file without a path ? + if (position == std::string::npos) { + return PathAndFilePair(std::string(), filePath); + } + + // This is full file-path pair + return PathAndFilePair(filePath.substr(0, + position), + filePath.substr(position + 1)); +} + +static int lambdaDeleteFile(const char *fpath, + const struct stat *sb, + int tflag, + struct FTW *ftwbuf) +{ + (void)sb; + (void)ftwbuf; + + switch (tflag) { + case FTW_D: + case FTW_DNR: + case FTW_DP: + LogInfo("Removing old temporary directory" << fpath); + return rmdir(fpath); + break; + default: + LogInfo("Unlinking old temporary file" << fpath); + return unlink(fpath); + break; + } + + return 0; +} +} // namespace anonymous + +namespace Jobs { +namespace WidgetInstall { +TaskUnzip::TaskUnzip(InstallerContext &installerContext) : + DPL::TaskDecl<TaskUnzip>(this), + m_installerContext(installerContext) +{ + // Install steps + AddStep(&TaskUnzip::StepCreateTempPath); + AddStep(&TaskUnzip::StepUnzipPrepare); + AddStep(&TaskUnzip::StepUnzipProgress); + AddStep(&TaskUnzip::StepUnzipFinished); + + AddAbortStep(&TaskUnzip::StepAbort); +} + +void TaskUnzip::ExtractFile(DPL::ZipInput::File *input, + const std::string &destFileName) +{ + Try + { + DPL::AbstractWaitableInputAdapter inputAdapter(input); + DPL::FileOutput output(destFileName); + + DPL::Copy(&inputAdapter, &output); + } + Catch(DPL::FileOutput::Exception::OpenFailed) + { + ReThrowMsg(Exceptions::ExtractFileFailed, destFileName); + } + Catch(DPL::CopyFailed) + { + ReThrowMsg(Exceptions::ExtractFileFailed, destFileName); + } +} + +void TaskUnzip::StepCreateTempPath() +{ + LogInfo("Step: Creating temporary path"); + + // Temporary path + std::ostringstream tempPathBuilder; + + tempPathBuilder << GlobalConfig::GetUserInstalledWidgetPath(); + tempPathBuilder << "/"; + tempPathBuilder << "widget"; + tempPathBuilder << "/"; + tempPathBuilder << TEMPORARY_PATH_POSTFIX; + tempPathBuilder << "_"; + + timeval tv; + gettimeofday(&tv, NULL); + tempPathBuilder << + (static_cast<unsigned long long>(tv.tv_sec) * 1000000ULL + + static_cast<unsigned long long>(tv.tv_usec)); + + std::string tempPath = tempPathBuilder.str(); + + // Remove old path if any + struct stat fileInfo; + + // FIXME: what if there are more then maxDepth recursive directories + static const int maxDepth = 1024; + if (stat(tempPath.c_str(), &fileInfo) == 0) { + int error = nftw( + tempPath.c_str(), lambdaDeleteFile, maxDepth, FTW_DEPTH); + + if (error == -1) { + ThrowMsg(DPL::CommonException::InternalError, + DPL::GetErrnoString()); + } + } + // Create new path + FileUtils::MakePath(tempPath, TEMPORARY_PATH_MODE); + + // Step succedded, save temporary widget path + m_installerContext.tempWidgetPath = tempPath; + m_installerContext.unzipStarted = true; +} + +void TaskUnzip::StepUnzipPrepare() +{ + LogInfo("Prepare to unzip..."); + + Try + { + m_zip.Reset(new DPL::ZipInput(m_installerContext.widgetFilePath)); + LogInfo("Widget package comment: " << m_zip->GetGlobalComment()); + + // Widget package must not be empty + if (m_zip->empty()) { + ThrowMsg(Exceptions::ZipEmpty, m_installerContext.widgetFilePath); + } + + // Set iterator to first file + m_zipIterator = m_zip->begin(); + } + Catch(DPL::ZipInput::Exception::OpenFailed) + { + ReThrowMsg(Exceptions::OpenZipFailed, m_installerContext.widgetFilePath); + } +} + +void TaskUnzip::StepUnzipProgress() +{ + // Show file info + LogInfo("Unzipping: '" << m_zipIterator->name << + "', Comment: '" << m_zipIterator->comment << + "', Compressed size: " << m_zipIterator->compressedSize << + ", Uncompressed size: " << m_zipIterator->uncompressedSize); + + // Normalize file paths + // FIXME: Implement checking for invalid characters + + // Extract file or path + std::string fileName = m_zipIterator->name; + + if (fileName[fileName.size() - 1] == '/') { + // This is path + std::string newPath = m_installerContext.tempWidgetPath + "/" + + fileName.substr(0, fileName.size() - 1); + LogPedantic("Path to extract: " << newPath); + + // Create path in case of it is empty + FileUtils::MakePath(newPath, TEMPORARY_PATH_MODE); + } else { + // This is regular file + std::string fileExtractPath = + m_installerContext.tempWidgetPath + "/" + fileName; + + LogPedantic("File to extract: " << fileExtractPath); + + // Split into pat & file pair + PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath); + + LogPedantic("Path and file: " << + pathAndFile.path << + " : " << pathAndFile.file); + + // First, ensure that path exists + FileUtils::MakePath(pathAndFile.path, TEMPORARY_PATH_MODE); + + Try + { + // Open file + DPL::ScopedPtr<DPL::ZipInput::File> file( + m_zip->OpenFile(fileName)); + + // Extract single file + ExtractFile(file.Get(), fileExtractPath); + } + Catch(DPL::ZipInput::Exception::OpenFileFailed) + { + ThrowMsg(Exceptions::ExtractFileFailed, fileName); + } + } + + // Check whether there are more files to extract + if (++m_zipIterator == m_zip->end()) { + LogInfo("Unzip progress finished successfuly"); + } else { + SwitchToStep(&TaskUnzip::StepUnzipProgress); + } +} + +void TaskUnzip::StepUnzipFinished() +{ + // Unzip finished, close internal structures + m_zip.Reset(); + + m_installerContext.unzipFinished = true; + + // Done + LogInfo("Unzip finished"); +} + +void TaskUnzip::StepAbort() +{ + LogError("[Unzip Task] Aborting... (removing temporary dir: " << + m_installerContext.tempWidgetPath << " )"); + + static const int maxDepth = 1024; + struct stat fileInfo; + if (stat(m_installerContext.tempWidgetPath.c_str(), &fileInfo) == 0) { + nftw(m_installerContext.tempWidgetPath.c_str(), + lambdaDeleteFile, maxDepth, FTW_DEPTH); + } +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_unzip.h b/src/jobs/widget_install/task_unzip.h new file mode 100644 index 0000000..3b0de40 --- /dev/null +++ b/src/jobs/widget_install/task_unzip.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_unzip.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task unzip + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UNZIP_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UNZIP_H + +#include <dpl/zip_input.h> +#include <dpl/scoped_ptr.h> +#include <dpl/task.h> +#include <string> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskUnzip : + public DPL::TaskDecl<TaskUnzip> +{ + private: + // Installation context + InstallerContext &m_installerContext; + + // Unzip state + DPL::ScopedPtr<DPL::ZipInput> m_zip; + DPL::ZipInput::const_iterator m_zipIterator; + + void ExtractFile(DPL::ZipInput::File *input, + const std::string &destFileName); + + // Steps + void StepCreateTempPath(); + + void StepUnzipPrepare(); + void StepUnzipProgress(); + void StepUnzipFinished(); + void StepAbort(); + + public: + TaskUnzip(InstallerContext &installerContext); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UNZIP_H diff --git a/src/jobs/widget_install/task_widget_config.cpp b/src/jobs/widget_install/task_widget_config.cpp new file mode 100644 index 0000000..8f4710f --- /dev/null +++ b/src/jobs/widget_install/task_widget_config.cpp @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_widget_config.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task widget config + */ +#include <string> +#include <sstream> +#include <dpl/foreach.h> +#include <dpl/errno_string.h> +#include <dpl/wrt-dao-rw/feature_dao.h> +#include <dpl/utils/wrt_utility.h> +#include <root_parser.h> +#include <powder_parser.h> +#include <widget_parser.h> +#include <parser_runner.h> +#include <libiriwrapper.h> +#include <widget_install/task_widget_config.h> +#include <widget_install/job_widget_install.h> +#include <widget_install/widget_install_errors.h> +#include <widget_install/widget_install_context.h> +#include <dpl/utils/file_utils.h> +#include <dpl/utils/mime_type_utils.h> +#include <sys/stat.h> +#include "wrt_powder_info_util.h" +#include <dpl/utils/wrt_global_settings.h> + +namespace { // anonymous +const char *WIDGET_SCHEMA = "widget"; +const WidgetHandle WIDGET_HANDLE_START_VALUE = 1000; +const char * AGE_RATING = "Age Rating: "; +const char * CATEGORY = "Category: "; +const char * LEVEL = "Level: "; +const char * CONTEXT = "Context: "; +const DPL::String POWDER_INFO = DPL::FromUTF8String("Powder Info"); +const DPL::String POWDER_PASSWORD = DPL::FromUTF8String( + "Parental Mode is ON.<br>" + "Please enter your password"); +const DPL::String WIDGET_HEAD = DPL::FromUTF8String("Widget information"); +const std::string OK_BUTTON_LABEL = "OK"; +const std::string CANCEL_BUTTON_LABEL = "Cancel"; +const DPL::String BR = DPL::FromUTF8String("<br>"); +const DPL::String DOUBLE_BR = DPL::FromUTF8String("<br><br>"); +const DPL::String POWDER_HEAD = DPL::FromUTF8String("Powder information"); +const DPL::String FEATURE_HEAD = DPL::FromUTF8String("Feature information"); +} // namespace anonymous + +namespace Jobs { +namespace WidgetInstall { +void InstallerTaskWidgetPopupData::PopupData::addWidgetInfo( + const DPL::String &head, + const DPL::String &info) +{ + widgetInfo += head; + widgetInfo += DOUBLE_BR; + widgetInfo += info; + widgetInfo += BR; +} + +TaskWidgetConfig::TaskWidgetConfig(InstallerContext& installContext) : + DPL::TaskDecl<TaskWidgetConfig>(this), + m_installContext(installContext), + m_installCancel(false) +{ + AddStep(&TaskWidgetConfig::StepProcessConfigurationFile); + AddStep(&TaskWidgetConfig::ReadLocaleFolders); + AddStep(&TaskWidgetConfig::ProcessLocalizedStartFiles); + AddStep(&TaskWidgetConfig::ProcessLocalizedIcons); + AddStep(&TaskWidgetConfig::StepProcessPowderFile); + AddStep(&TaskWidgetConfig::StepVerifyFeatures); + + //in case of tests, no popups are shown + if (GlobalSettings::GetPopupsEnabledFlag()) { + AddStep(&TaskWidgetConfig::StepShowWidgetInfo); + AddStep(&TaskWidgetConfig::StepCancelWidgetInstallation); + } +} + +void TaskWidgetConfig::StepProcessConfigurationFile() +{ + Try + { + WidgetConfigurationManagerSingleton::Instance().processFile( + m_installContext.tempWidgetPath, + m_installContext.widgetConfig); + } + Catch(WidgetConfigurationManager::Exception::ProcessFailed) + { + LogError("Parsing failed."); + ReThrow(Exceptions::WidgetConfigFileInvalid); + } + Try + { + // To get widget type for distribute WAC, TIZEN WebApp + setApplicationType(); + } + Catch(WidgetConfigurationManager::Exception::ProcessFailed) + { + LogError("Config.xml has more than one namespace"); + ReThrow(Exceptions::WidgetConfigFileInvalid); + } + + m_installContext.job->SetProgressFlag(true); + m_installContext.job->UpdateProgress( + InstallerContext::INSTALL_WIDGET_CONFIG1, + "Parsing was suscessfull"); +} + +void TaskWidgetConfig::ReadLocaleFolders() +{ + LogDebug("Reading locale"); + //Adding default locale + m_localeFolders.insert(L""); + + std::string localePath = m_installContext.tempWidgetPath + "/locales"; + DIR* localeDir = opendir(localePath.c_str()); + if (!localeDir) { + LogDebug("No /locales directory in the widget package."); + return; + } + + struct dirent* dirent; + struct stat statStruct; + do { + errno = 0; + if ((dirent = readdir(localeDir))) { + DPL::String dirName = DPL::FromUTF8String(dirent->d_name); + std::string absoluteDirName = localePath + "/"; + absoluteDirName += dirent->d_name; + + if (stat(absoluteDirName.c_str(), &statStruct) != 0) { + LogError("stat() failed with " << DPL::GetErrnoString()); + continue; + } + + if (S_ISDIR(statStruct.st_mode)) { + //Yes, we ignore current, parent & hidden directories + if (dirName[0] != L'.') { + LogDebug("Adding locale directory \"" << dirName << "\""); + m_localeFolders.insert(dirName); + } + } + } + } + while (dirent); + + if (errno != 0) { + LogError("readdir() failed with " << DPL::GetErrnoString()); + } + + if (closedir(localeDir)) { + LogError("closedir() failed with " << DPL::GetErrnoString()); + } +} + +void TaskWidgetConfig::ProcessLocalizedStartFiles() +{ + typedef DPL::String S; + ProcessStartFile( + m_installContext.widgetConfig.configInfo.startFile, + m_installContext.widgetConfig.configInfo. + startFileContentType, + m_installContext.widgetConfig.configInfo.startFileEncoding, + true); + ProcessStartFile(S(L"index.htm"), S(L"text/html")); + ProcessStartFile(S(L"index.html"), S(L"text/html")); + ProcessStartFile(S(L"index.svg"), S(L"image/svg+xml")); + ProcessStartFile(S(L"index.xhtml"), S(L"application/xhtml+xml")); + ProcessStartFile(S(L"index.xht"), S(L"application/xhtml+xml")); + // TODO: (l.wrzosek) we need better check if in current locales widget is valid. + FOREACH(it, m_installContext.widgetConfig.localizationData.startFiles) { + if (it->propertiesForLocales.size() > 0) { + return; + } + } + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + L"The Widget has no valid start file"); +} + +void TaskWidgetConfig::ProcessStartFile(const DPL::OptionalString& path, + const DPL::OptionalString& type, + const DPL::OptionalString& encoding, + bool typeForcedInConfig) +{ + using namespace WrtDB; + + if (!!path) { + WidgetRegisterInfo::LocalizedStartFile startFileData; + startFileData.path = *path; + + FOREACH(i, m_localeFolders) { + DPL::String pathPrefix = *i; + if (!pathPrefix.empty()) { + pathPrefix = L"locales/" + pathPrefix + L"/"; + } + + DPL::String relativePath = pathPrefix + *path; + DPL::String absolutePath = DPL::FromUTF8String( + m_installContext.tempWidgetPath) + L"/" + relativePath; + + // get property data from packaged app + if (FileUtils::FileExists(absolutePath)) { + WidgetRegisterInfo::StartFileProperties startFileProperties; + if (!!type) { + startFileProperties.type = *type; + } else { + startFileProperties.type = + MimeTypeUtils::identifyFileMimeType(absolutePath); + } + + //proceed only if MIME type is supported + if (MimeTypeUtils::isMimeTypeSupportedForStartFile( + startFileProperties.type)) + { + if (!!encoding) { + startFileProperties.encoding = *encoding; + } else { + MimeTypeUtils::MimeAttributes attributes = + MimeTypeUtils::getMimeAttributes( + startFileProperties.type); + if (attributes.count(L"charset") > 0) { + startFileProperties.encoding = + attributes[L"charset"]; + } else { + startFileProperties.encoding = L"UTF-8"; + } + } + + startFileData.propertiesForLocales[*i] = + startFileProperties; + } else { + //9.1.16.5.content.8 + //(there seems to be no similar requirement in .6, + //so let's throw only when mime type is + // provided explcitly in config.xml) + if (typeForcedInConfig) { + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Unsupported MIME type for start file."); + } + } + } else { + // set property data for hosted start url + // Hosted start url only support TIZEN WebApp + if (m_installContext.widgetConfig.type == + APP_TYPE_TIZENWEBAPP) + { + const char *startPath = + DPL::ToUTF8String(startFileData.path).c_str(); + if (strstr(startPath, "http") == startPath) { + WidgetRegisterInfo::StartFileProperties + startFileProperties; + if (!!type) { + startFileProperties.type = *type; + } + if (!!encoding) { + startFileProperties.encoding = *encoding; + } + startFileData.propertiesForLocales[*i] = + startFileProperties; + } + } + } + } + + m_installContext.widgetConfig.localizationData.startFiles.push_back( + startFileData); + } +} + +void TaskWidgetConfig::ProcessLocalizedIcons() +{ + using namespace WrtDB; + ProcessIcon(ConfigParserData::Icon(L"icon.svg")); + ProcessIcon(ConfigParserData::Icon(L"icon.ico")); + ProcessIcon(ConfigParserData::Icon(L"icon.png")); + ProcessIcon(ConfigParserData::Icon(L"icon.gif")); + ProcessIcon(ConfigParserData::Icon(L"icon.jpg")); + + FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList) + { + ProcessIcon(*i); + } +} + +void TaskWidgetConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon) +{ + bool isAnyIconExisted = false; + //In case a default filename is passed as custom filename in config.xml, we + //need to keep a set of already processed filenames to avoid icon duplication + //in database. + + using namespace WrtDB; + + if (m_processedIconSet.count(icon.src) > 0) { + return; + } + + m_processedIconSet.insert(icon.src); + + LocaleSet localesAvailableForIcon; + + FOREACH(i, m_localeFolders) + { + DPL::String pathPrefix = *i; + if (!pathPrefix.empty()) { + pathPrefix = L"locales/" + pathPrefix + L"/"; + } + + DPL::String relativePath = pathPrefix + icon.src; + DPL::String absolutePath = DPL::FromUTF8String( + m_installContext.tempWidgetPath) + L"/" + relativePath; + + if (FileUtils::FileExists(absolutePath)) { + isAnyIconExisted = true; + DPL::String type = MimeTypeUtils::identifyFileMimeType(absolutePath); + + if (MimeTypeUtils::isMimeTypeSupportedForIcon(type)) { + localesAvailableForIcon.insert(*i); + } + LogInfo("Icon absolutePath :" << absolutePath << + ", assigned locale :" << *i); + } + } + + if(isAnyIconExisted) + { + WidgetRegisterInfo::LocalizedIcon localizedIcon(icon, + localesAvailableForIcon); + m_installContext.widgetConfig.localizationData.icons.push_back( + localizedIcon); + } +} + +void TaskWidgetConfig::StepProcessPowderFile(void) +{ + using namespace WrtDB; + const std::string& path = m_installContext.tempWidgetPath; + WidgetRegisterInfo* widgetConfiguration = + &m_installContext.widgetConfig; + + LogInfo("Process powder for guid " << + widgetConfiguration->guid); + if (!!widgetConfiguration->guid) { + LibIri::Wrapper iri(DPL::ToUTF8String( + *widgetConfiguration->guid).c_str()); + DPL::String widgetHost; + DPL::String widgetPath; + if (NULL != iri.m_Iri->host) { + widgetHost = DPL::FromUTF8String(iri.m_Iri->host); + } + if (NULL != iri.m_Iri->path) { + widgetPath = DPL::FromUTF8String(iri.m_Iri->path); + } + PowderParserData parserData(&widgetConfiguration->powderDescription, + widgetHost, widgetPath); + ConfigParserData::StringsList& descriptions = + widgetConfiguration->configInfo.powderDescriptionLinks; + + FOREACH(linkIter, descriptions) + { + LogInfo("Process powder link: " << *linkIter); + LibIri::Wrapper link(DPL::ToUTF8String(*linkIter).c_str()); + LogInfo("Parser link" << link); + if (strcmp(link.m_Iri->scheme, WIDGET_SCHEMA) == 0) { + if (NULL != link.m_Iri->host) { + std::ostringstream stream; + //FIXME: Current libiri library is not able to parse + // URL: widget:/powder.xml Field host + // is filed with path + stream << path << "/" << link.m_Iri->host; + ParserRunner().Parse( + stream.str(), + ElementParserPtr(new + RootParser<PowderParser>(&parserData, + DPL:: + FromUTF32String( + L"powder")))); + } else { + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Powder link " << *linkIter << " path empty."); + } + } else { + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Powder link " << + *linkIter << + " schema not supported."); + } + } + } + + //TODO:FIXME make progress valid + m_installContext.job->UpdateProgress( + InstallerContext::INSTALL_WIDGET_CONFIG1, + "Widget Config powder step Finished"); +} + +void TaskWidgetConfig::AnswerCallback(const DPL::Popup::AnswerCallbackData &answer) +{ + LogInfo("Callback called"); + if (WRT_POPUP_BUTTON_CANCEL == answer.buttonAnswer) { + m_installCancel = WRT_POPUP_BUTTON_CANCEL; + } + m_installContext.job->Resume(); +} + +void TaskWidgetConfig::StepCancelWidgetInstallation() +{ + if (WRT_POPUP_BUTTON_CANCEL == m_installCancel) { + ThrowMsg(Exceptions::NotAllowed, "Widget not allowed"); + } +} + +//TODO this step is not added in constructor +void TaskWidgetConfig::StepShowPowderPasswordCancel() +{ + if (WRT_POPUP_BUTTON_CANCEL == m_installCancel) { + ThrowMsg(Exceptions::NotAllowed, "Parental Mode is ON"); + } +} + +void TaskWidgetConfig::PopupCreate() +{ + m_installContext.job->Pause(); + using namespace DPL::Popup; + CtrlPopupPtr popup = PopupControllerSingleton::Instance().CreatePopup(); + popup->SetTitle(DPL::ToUTF8String(WIDGET_HEAD)); + popup->Append(new PopupObject::Label( + DPL::ToUTF8String(m_popupData.widgetInfo))); + m_popupData.widgetInfo.clear(); + popup->Append(new PopupObject::Button(OK_BUTTON_LABEL, + WRT_POPUP_BUTTON_OK)); + popup->Append(new PopupObject::Button(CANCEL_BUTTON_LABEL, + WRT_POPUP_BUTTON_CANCEL)); + ListenForAnswer(popup); + ShowPopupEvent event(popup, MakeAnswerCallback( + this, + &TaskWidgetConfig:: + AnswerCallback), DPL::Event::UNDEFINED_LOOP_HANDLE); + CONTROLLER_POST_EVENT(PopupController, event); +} + +DPL::String TaskWidgetConfig::createPowderInfo() const +{ + WrtDB::Powder::Description &powderDescription = + m_installContext.widgetConfig.powderDescription; + std::ostringstream powderInfo; + if (!!powderDescription.ageRating) { + powderInfo << AGE_RATING; + powderInfo << *powderDescription.ageRating; + powderInfo << BR; + } + FOREACH(categoriesIterator, powderDescription.categories) { + powderInfo << CATEGORY; + powderInfo << PowderInfoUtilSingleton::Instance(). + getCategoryLabel(categoriesIterator->first); + powderInfo << BR; + + FOREACH(levelIterator, categoriesIterator->second.levels) { + powderInfo << LEVEL; + powderInfo << static_cast<int>(levelIterator->level); + powderInfo << BR; + + FOREACH(contextIterator, levelIterator->context) { + powderInfo << CONTEXT; + powderInfo << PowderInfoUtilSingleton::Instance(). + getContextLabel(*contextIterator); + powderInfo << BR; + } + } + } + + return DPL::FromUTF8String(powderInfo.str()); +} + +void TaskWidgetConfig::StepShowWidgetInfo() +{ + if (!createPowderInfo().empty()) { + m_popupData.addWidgetInfo(POWDER_HEAD, + createPowderInfo()); + } + + if (!m_popupData.widgetInfo.empty()) { + PopupCreate(); + m_installContext.job->UpdateProgress( + InstallerContext::INSTALL_WIDGET_CONFIG2, + "Show Widget Info Finished"); + } +} + +//TODO this step is not added in constructor +void TaskWidgetConfig::StepShowPowderPassword() +{ + using namespace WrtDB; + if (GlobalDAOReadOnly::GetParentalMode()) { + m_popupData.addWidgetInfo(POWDER_INFO, POWDER_PASSWORD); + } + m_installContext.job->UpdateProgress( + InstallerContext::INSTALL_WIDGET_CONFIG2, + "Show Powder Password Finished"); +} + +void TaskWidgetConfig::StepVerifyFeatures() +{ + using namespace WrtDB; + ConfigParserData &data = m_installContext.widgetConfig.configInfo; + ConfigParserData::FeaturesList list = data.featuresList; + ConfigParserData::FeaturesList newList; + + //in case of tests, this variable is unused + std::string featureInfo; + FOREACH(it, list) + { + // check feature vender for permission + // WAC, TIZEN WebApp cannot use other feature + if (!isFeatureAllowed(m_installContext.widgetConfig.type.appType, + it->name)) + { + LogInfo("This application type not allowed to use this feature"); + ThrowMsg( + Exceptions::WidgetConfigFileInvalid, + "This app type [" << + m_installContext.widgetConfig.type.getApptypeToString() << + "] cannot be allowed to use [" << + DPL::ToUTF8String(it->name) + "] feature"); + } + if (!WrtDB::FeatureDAOReadOnly::isFeatureInstalled( + DPL::ToUTF8String(it->name))) { + LogWarning("Feature not found. Checking if required :[" << + DPL::ToUTF8String(it->name) << "]"); + + if (it->required) { + LogWarning( + "Required Features missing, Installation topped: [" << + DPL::ToUTF8String(it->name) << "]"); + + ThrowMsg( + Exceptions::WidgetConfigFileInvalid, + "Widget cannot be installedm equired feature is missing:[" + + + DPL::ToUTF8String(it->name) + "]"); + } + } else { + newList.insert(*it); + featureInfo += DPL::ToUTF8String(it->name); + featureInfo += DPL::ToUTF8String(BR); + } + } + data.featuresList = newList; + if (!featureInfo.empty()) { + m_popupData.addWidgetInfo(FEATURE_HEAD, + DPL::FromUTF8String(featureInfo)); + } + + m_installContext.job->UpdateProgress( + InstallerContext::INSTALL_WIDGET_CONFIG2, + "Widget Config step2 Finished"); +} + +void TaskWidgetConfig::setApplicationType() +{ + using namespace WrtDB; + WidgetRegisterInfo* widgetInfo = &(m_installContext.widgetConfig); + ConfigParserData* configInfo = &(widgetInfo->configInfo); + + FOREACH(iterator, configInfo->nameSpaces) { + LogInfo("namespace = [" << *iterator << "]"); + AppType currentAppType = APP_TYPE_UNKNOWN; + + if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) { + continue; + } else if (*iterator == + ConfigurationNamespace::JilWidgetNamespaceName) { + currentAppType = APP_TYPE_WAC10; + } else if ( + *iterator == + ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement || + *iterator == + ConfigurationNamespace::WacWidgetNamespaceName) + { + currentAppType = APP_TYPE_WAC20; + } else if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) { + currentAppType = APP_TYPE_TIZENWEBAPP; + } + + if (widgetInfo->type == APP_TYPE_UNKNOWN) { + widgetInfo->type = currentAppType; + } else if (widgetInfo->type == currentAppType) { + continue; + } else { + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Config.xml has more than one namespace"); + } + } + + // If there is no define, type set to WAC 2.0 + if (widgetInfo->type == APP_TYPE_UNKNOWN) { + widgetInfo->type = APP_TYPE_WAC20; + } + + LogInfo("type = [" << widgetInfo->type.getApptypeToString() << "]"); +} + +bool TaskWidgetConfig::isFeatureAllowed(WrtDB::AppType appType, + DPL::String featureName) +{ + using namespace WrtDB; + LogInfo("AppType = [" << + WidgetType(appType).getApptypeToString() << "]"); + LogInfo("FetureName = [" << featureName << "]"); + + AppType featureType = APP_TYPE_UNKNOWN; + const char* feature = DPL::ToUTF8String(featureName).c_str(); + // check prefix of feature name + if (strstr(feature, PluginsPrefix::TIZENPluginsPrefix) == feature) { + // Tizen WebApp feature + featureType = APP_TYPE_TIZENWEBAPP; + } else if (strstr(feature, PluginsPrefix::WACPluginsPrefix) == feature) { + // WAC 2.0 feature + featureType = APP_TYPE_WAC20; + } else if (strstr(feature, PluginsPrefix::W3CPluginsPrefix) == feature) { + // W3C standard feature + // Both WAC and TIZEN WebApp are possible to use W3C plugins + return true; + } else { + // unknown feature + // unknown feature will be checked next step + return true; + } + + if (appType == featureType) { + return true; + } + return false; +} + +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_widget_config.h b/src/jobs/widget_install/task_widget_config.h new file mode 100644 index 0000000..0655964 --- /dev/null +++ b/src/jobs/widget_install/task_widget_config.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_widget_config.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task widget config + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_WIDGET_CONFIG_H +#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_WIDGET_CONFIG_H + +#include <WidgetConfigurationManager.h> +#include <dpl/task.h> +#include <dpl/task_list.h> +#include <dpl/string.h> +#include <dpl/event/nested_loop.h> +#include <wrt_error.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <set> +#include <dpl/popup/popup_controller.h> +#include <dpl/popup/popup_manager.h> +#include <dpl/popup/popup_renderer.h> +#include <wrt_common_types.h> + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +namespace InstallerTaskWidgetPopupData { +struct PopupData +{ + DPL::String widgetInfo; + void addWidgetInfo(const DPL::String &head, + const DPL::String &info); +}; +} // InstalllerTaskWidgetPopupData + +class TaskWidgetConfig : + public DPL::TaskDecl<TaskWidgetConfig>, + public DPL::Popup::PopupControllerUser +{ + private: + enum PowderInfoButton + { + WRT_POPUP_BUTTON_OK, WRT_POPUP_BUTTON_CANCEL + }; + + InstallerContext& m_installContext; + WrtDB::LocaleSet m_localeFolders; + std::set<DPL::String> m_processedIconSet; + bool m_installCancel; + InstallerTaskWidgetPopupData::PopupData m_popupData; + + void StepProcessConfigurationFile(); + void ReadLocaleFolders(); + void ProcessLocalizedStartFiles(); + void ProcessStartFile(const DPL::OptionalString& path, + const DPL::OptionalString& type, + const DPL::OptionalString& encoding = DPL::OptionalString::Null, + bool typeForcedInConfig = false); + void ProcessLocalizedIcons(); + void ProcessIcon(const WrtDB::ConfigParserData::Icon& icon); + void StepProcessPowderFile(); + void StepVerifyFeatures(); + void StepShowWidgetInfo(); + void StepPowderCancel(); + void StepFeatureCancel(); + void StepCancelWidgetInstallation(); + void StepShowPowderPassword(); + void StepShowPowderPasswordCancel(); + void PopupCreate(); + DPL::String createPowderInfo() const; + void AnswerCallback(const DPL::Popup::AnswerCallbackData& answer); + DPL::String createAuthorWidgetInfo() const; + void setApplicationType(); + bool isFeatureAllowed( + WrtDB::AppType appType, DPL::String featureName); + + public: + TaskWidgetConfig(InstallerContext& installTaskContext); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_WIDGET_CONFIG_H diff --git a/src/jobs/widget_install/wac_security.cpp b/src/jobs/widget_install/wac_security.cpp new file mode 100644 index 0000000..b8ce123 --- /dev/null +++ b/src/jobs/widget_install/wac_security.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file wac_security.cpp + * @author Krzysztof Jackiewicz(k.jackiewicz@samsung.com) + * @version 1.0 + * @brief + */ + +#include "wac_security.h" +#include <dpl/foreach.h> + +namespace Jobs { +namespace WidgetInstall { + +void WacSecurity::getCertificateChainList( + WrtDB::CertificateChainList& list) const +{ + FOREACH(certIter,mCertificateChainList) + list.push_back(certIter->toBase64String()); +} + +} // namespace WidgetInstall +} // namespace Jobs diff --git a/src/jobs/widget_install/wac_security.h b/src/jobs/widget_install/wac_security.h new file mode 100644 index 0000000..702a8f4 --- /dev/null +++ b/src/jobs/widget_install/wac_security.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file wac_security.h + * @author Krzysztof Jackiewicz(k.jackiewicz@samsung.com) + * @version 1.0 + * @brief + */ + +#ifndef WACSECURITY_H_ +#define WACSECURITY_H_ + +#include <dpl/wrt-dao-ro/widget_dao_read_only.h> +#include <vcore/Certificate.h> +#include <vcore/CertificateCollection.h> + +namespace Jobs { +namespace WidgetInstall { + +class WacSecurity : public WrtDB::IWacSecurity +{ + public: + WacSecurity() : + mRecognized(false), + mDistributorSigned(false), + mWacSigned(false) + { + } + + // from IWacSecurity + virtual const WrtDB::WidgetCertificateDataList& getCertificateList() const + { + return mCertificateList; + } + + virtual bool isRecognized() const { return mRecognized; } + + virtual bool isDistributorSigned() const { return mDistributorSigned; } + + virtual bool isWacSigned() const { return mWacSigned; } + + virtual void getCertificateChainList( + WrtDB::CertificateChainList& list) const; + + void setRecognized(bool recognized) { mRecognized = recognized; } + void setDistributorSigned(bool distributorSigned) + { + mDistributorSigned = distributorSigned; + } + void setWacSigned(bool wacSigned) { mWacSigned = wacSigned; } + + ValidationCore::CertificatePtr getAuthorCertificatePtr() const { return mAuthorCertificate;} + ValidationCore::CertificateCollectionList& getCertificateChainListRef() + { + return mCertificateChainList; + } + + WrtDB::WidgetCertificateDataList& getCertificateListRef() + { + return mCertificateList; + } + + private: + // This data are used to evaluate policy + WrtDB::WidgetCertificateDataList mCertificateList; + + // author signature verified + bool mRecognized; + // known distribuor + bool mDistributorSigned; + // distributor is wac + bool mWacSigned; + // Author end entity certificate. + // Information from this certificate are shown to user + // during installation process. + ValidationCore::CertificatePtr mAuthorCertificate; + // This certificates are used by OCSP/CRL + ValidationCore::CertificateCollectionList mCertificateChainList; +}; + +} // namespace WidgetInstall +} // namespace Jobs + +#endif /* WACSECURITY_H_ */ diff --git a/src/jobs/widget_install/widget_install_context.h b/src/jobs/widget_install/widget_install_context.h new file mode 100644 index 0000000..c277dea --- /dev/null +++ b/src/jobs/widget_install/widget_install_context.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file installer_structs.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief Definition file of installer tasks data structures + */ +#ifndef INSTALLER_CONTEXT_H +#define INSTALLER_CONTEXT_H + +#include <string> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <widget_install/wac_security.h> +#include <feature_logic.h> +#include <widget_install/widget_update_info.h> + +namespace Jobs { +namespace WidgetInstall { +class JobWidgetInstall; +} //namespace Jobs +} //namespace WidgetInstall + +class WidgetModel; + +struct InstallerContext +{ + typedef enum InstallStepEnum + { + INSTALL_START = 0, + INSTALL_WIDGET_CONFIG1, + INSTALL_WIDGET_CONFIG2, + INSTALL_WIDGET_CONFIG3, + INSTALL_WIDGET_CONFIG4, + INSTALL_WIDGET_CONFIG5, + INSTALL_DB_UPDATE, + INSTALL_RENAME_PATH, + INSTALL_CREATE_DESKTOP, + INSTALL_CREATE_EXECFILE, + INSTALL_COPY_ICONFILE, + INSTALL_CREATE_PRIVATE_STORAGE, + INSTALL_END + } InstallStep; + + // Installation state variables + std::string widgetFilePath; ///< Source widget zip file + std::string tempWidgetPath; ///< Unpacked widget temporary path + WrtDB::WidgetRegisterInfo widgetConfig; ///< WidgetConfigInfo + DPL::Optional<WrtDB::DbWidgetHandle> widgetHandle; + Jobs::WidgetInstall::WacSecurity wacSecurity;///< Widget Domain information. + bool unzipStarted; + ///< flag that indicates whether installer starts to unzip .wgt file + bool unzipFinished; + ///< flag that indicates whether installer finishes to unzip completely. + InstallStep installStep; ///< current step of installation + Jobs::WidgetInstall::JobWidgetInstall *job; + ///< pointer of instance of JobWidgetInstall + WidgetUpdateInfo::ExistingWidgetInfo existingWidgetInfo; + ///< Whether this is an update or normal installation + Jobs::WidgetInstall::FeatureLogicPtr featureLogic; + /** List of dev-caps that get "static" permission (will always + * have PERMIT from ACE Policy). They will therefore receive + * static SMACK permission. (They may be forbidden because + * of ACE User Settings, but for now we do not protect this + * case with SMACK). */ + std::set<DPL::String> staticPermittedDevCaps; +}; + +#endif // INSTALLER_CONTEXT_H diff --git a/src/jobs/widget_install/widget_install_errors.h b/src/jobs/widget_install/widget_install_errors.h new file mode 100644 index 0000000..5ed746e --- /dev/null +++ b/src/jobs/widget_install/widget_install_errors.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file installer_errors.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +#ifndef INSTALLER_ERRORS_H_ +#define INSTALLER_ERRORS_H_ + +#include <dpl/exception.h> +#include <job_exception_base.h> + +//TODO SafeException(...) + +namespace Jobs { +namespace WidgetInstall { +namespace Exceptions { +enum Type +{ + Success, ///< Success + + ErrorInvalidWidgetPackage, ///< ? + ErrorWidgetDoesNotExist, ///< ? + ErrorFactoryWidget, ///< Widget is factory installed, and cannot be uninstalled + ErrorAreadyUninstalling, ///< Widget is already being uninstalled + ErrorOutOfDiskSpace, ///< ? + ErrorInvalidPackage, ///< Widget signature is invalid. + ErrorAlreadyInstalled, ///< ? + ErrorInternal, ///< ? + ErrorParentalMode, ///< Widget cannot be installed when parental mode is active + ErrorNotAllowed, ///< Widget installation or update not allowed + ///< because violation of policy ocurred + ErrorDeferred, ///< Widget installation was deferred and will be continued when possible + ErrorDatabaseFailure, ///< Failure in database + ErrorRemovingFolderFailure, ///< Failure in removing existing widget folder + ErrorUnknown ///< Temporary error. Try to not use this. +}; + +DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown) + +// PREPARE +DECLARE_JOB_EXCEPTION(Base, NotAllowed, ErrorNotAllowed) +DECLARE_JOB_EXCEPTION(Base, Deferred, ErrorDeferred) + +//PARENTAL MODE +DECLARE_JOB_EXCEPTION(Base, ParentalModeActive, ErrorParentalMode) + +//UNZIP +DECLARE_JOB_EXCEPTION(Base, OpenZipFailed, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, GetZipGlobalInfoFailed, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, ZipEmpty, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, GetZippedFileInfoFailed, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, ZippedFileVersionTooNew, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, ExtractFileFailed, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, OutOfDiskSpace, ErrorOutOfDiskSpace) +DECLARE_JOB_EXCEPTION(Base, InternalError, ErrorInternal) + +//CERTIFY +DECLARE_JOB_EXCEPTION(Base, InvalidPackage, ErrorInvalidPackage) + +//WCONFIG +DECLARE_JOB_EXCEPTION(Base, WidgetConfigFileInvalid, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, WidgetPowderFileInvalid, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, NotInstalled, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, InstallationFailed, ErrorInvalidWidgetPackage) +DECLARE_JOB_EXCEPTION(Base, AlreadyInstalled, ErrorAlreadyInstalled) +DECLARE_JOB_EXCEPTION(Base, UnknownError, ErrorUnknown) +DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorDatabaseFailure) +DECLARE_JOB_EXCEPTION(Base, RemovingFolderFailure, ErrorRemovingFolderFailure) + +DECLARE_JOB_EXCEPTION(Base, CopyIconFailed, ErrorUnknown) +} //namespace +} //namespace +} //namespace + +#endif /* INSTALLER_ERRORS_H_ */ diff --git a/src/jobs/widget_install/widget_installer_struct.h b/src/jobs/widget_install/widget_installer_struct.h new file mode 100644 index 0000000..33674ad --- /dev/null +++ b/src/jobs/widget_install/widget_installer_struct.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file widget_installer_struct.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Grzegorz Krawczyk (g.krawczyk@samsung.com) + * @version 1.0 + * @brief Implementation file for widget installer struct + */ +#ifndef WRT_SRC_INSTALLER_CORE_INSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ +#define WRT_SRC_INSTALLER_CORE_INSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ + +//SYSTEM INCLUDES +#include <dpl/assert.h> + +//WRT INCLUDES +#include <job_base.h> +#include <job.h> +#include <widget_install/widget_install_errors.h> +#include <wrt_common_types.h> + +//Widget Installer typedefs +typedef void (*InstallerFinishedCallback)( + void *userParam, + WidgetHandle, + Jobs::WidgetInstall::Exceptions::Type); + +typedef void (*InstallerProgressCallback)(void *userParam, + ProgressPercent percent, + const ProgressDescription &); + +namespace WidgetUpdateMode { +enum Type +{ + Zero = 0, + + // Bits + NotInstalled = 1 << 0, + IncomingVersionNotStd = 1 << 1, + ExistingVersionNotStd = 1 << 2, + BothVersionsNotStd = 1 << 3, + ExistingVersionOlder = 1 << 4, + ExistingVersionEqual = 1 << 5, + ExistingVersionNewer = 1 << 6, + + // Policies + PolicyNeverUpdate = NotInstalled, + + PolicyWac = NotInstalled | + ExistingVersionOlder, + + PolicyAlwaysInstall = NotInstalled | + IncomingVersionNotStd | + ExistingVersionNotStd | + BothVersionsNotStd | + ExistingVersionOlder | + ExistingVersionEqual | + ExistingVersionNewer, + + PolicyForceInstall = PolicyAlwaysInstall +}; + +inline Type operator | (const Type &a, + const Type &b) +{ + return static_cast<Type>(static_cast<unsigned long>(a) | + static_cast<unsigned long>(b)); +} + +inline Type operator & (const Type &a, + const Type &b) +{ + return static_cast<Type>(static_cast<unsigned long>(a) & + static_cast<unsigned long>(b)); +} +} + +//TODO into namespace +//InstallationStruct +typedef Jobs::JobCallbacksBase<InstallerFinishedCallback, + InstallerProgressCallback> +WidgetInstallCallbackBase; + +//Widget Installation Struct +struct WidgetInstallationStruct : public WidgetInstallCallbackBase +{ + WidgetUpdateMode::Type updateMode; + + // It must be empty-constructible as a parameter of generic event + WidgetInstallationStruct() : updateMode(WidgetUpdateMode::Zero) + { + } + + WidgetInstallationStruct(InstallerFinishedCallback finished, + InstallerProgressCallback progress, + void *param, + WidgetUpdateMode::Type mode) : + WidgetInstallCallbackBase(finished, progress, param), + updateMode(mode) + { + } +}; + +#endif // WRT_SRC_INSTALLER_CORE_INSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ diff --git a/src/jobs/widget_install/widget_update_info.cpp b/src/jobs/widget_install/widget_update_info.cpp new file mode 100644 index 0000000..e0b124c --- /dev/null +++ b/src/jobs/widget_install/widget_update_info.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file widget_update_info.cpp + * @author Chung Jihoon (jihoon.chung@samsung.com) + * @version 1.0 + * @brief Implementation file for WidgetUpdateInfo + */ + +#include "widget_update_info.h" + +WidgetUpdateInfo::ExistingWidgetInfo::ExistingWidgetInfo() : + isExist(false), + existingHandle(0) +{ +} + +WidgetUpdateInfo::ExistingWidgetInfo::ExistingWidgetInfo( + const WidgetHandle handle, + const DPL::Optional<WidgetVersion> &version) : + isExist(true), + existingHandle(handle), + existingVersion(version) +{ +} + +WidgetUpdateInfo::ExistingWidgetInfo::ExistingWidgetInfo( + const WidgetHandle handle, + const DPL::Optional<DPL::String> &version) : + isExist(true), + existingHandle(handle) +{ + if (!!version) { + existingVersion = WidgetVersion(*version); + } +} + +WidgetUpdateInfo::WidgetUpdateInfo() : + existingWidgetInfo() +{ +} + +WidgetUpdateInfo::WidgetUpdateInfo( + const DPL::Optional<WrtDB::WidgetGUID> &guid, + const DPL::Optional<WidgetVersion> &version, + ExistingWidgetInfo widgetInfo) : + incomingGUID(guid), + incomingVersion(version), + existingWidgetInfo(widgetInfo) +{ +} diff --git a/src/jobs/widget_install/widget_update_info.h b/src/jobs/widget_install/widget_update_info.h new file mode 100644 index 0000000..d08540e --- /dev/null +++ b/src/jobs/widget_install/widget_update_info.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file widget_update_info.h + * @author Chung Jihoon (jihoon.chung@samsung.com) + * @version 1.0 + * @brief Header file for WidgetUpdateInfo + */ +#ifndef SRC_DOMAIN_WIDGET_UPDATE_INFO_H +#define SRC_DOMAIN_WIDGET_UPDATE_INFO_H + +#include <wrt_common_types.h> +#include <dpl/wrt-dao-ro/common_dao_types.h> + +/** + * WidgetUpdateInfo + * A structure to hold widget's information needed to be registered. + * @see WidgetConfigurationInfo + */ +struct WidgetUpdateInfo +{ + struct ExistingWidgetInfo + { + bool isExist; + WidgetHandle existingHandle; + DPL::Optional<WidgetVersion> existingVersion; + + ExistingWidgetInfo(); + ExistingWidgetInfo(const WidgetHandle handle, + const DPL::Optional<WidgetVersion> &version); + ExistingWidgetInfo(const WidgetHandle handle, + const DPL::Optional<DPL::String> &version); + }; + + // Incoming widget + DPL::Optional<WrtDB::WidgetGUID> incomingGUID; + DPL::Optional<WidgetVersion> incomingVersion; + // Existing widget + ExistingWidgetInfo existingWidgetInfo; + + WidgetUpdateInfo(); + WidgetUpdateInfo(const DPL::Optional<WrtDB::WidgetGUID> &guid, + const DPL::Optional<WidgetVersion> &version, + ExistingWidgetInfo widgetInfo); +}; + +#endif // SRC_DOMAIN_WIDGET_UPDATE_INFO_H diff --git a/src/jobs/widget_uninstall/job_widget_uninstall.cpp b/src/jobs/widget_uninstall/job_widget_uninstall.cpp new file mode 100644 index 0000000..8c1c5b8 --- /dev/null +++ b/src/jobs/widget_uninstall/job_widget_uninstall.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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_uninstall/job_widget_uninstall.h> +#include <widget_uninstall/task_check.h> +#include <widget_uninstall/task_db_update.h> +#include <widget_uninstall/task_remove_files.h> +#include <widget_uninstall/task_smack.h> + +using namespace WrtDB; + +namespace Jobs { +namespace WidgetUninstall { +JobWidgetUninstall::JobWidgetUninstall(WidgetHandle widgetHandle, + const WidgetUninstallationStruct &uninstallerStruct) : + Job(Uninstallation), + JobContextBase<WidgetUninstallationStruct>(uninstallerStruct) +{ + WidgetDAO dao(widgetHandle); + + m_context.widgetHandle = widgetHandle; + m_context.removeStarted = false; + m_context.removeFinished = false; + m_context.uninstallStep = UninstallerContext::UNINSTALL_START; + m_context.job = this; + + AddTask(new TaskSmack(m_context)); + AddTask(new TaskCheck(m_context)); + AddTask(new TaskRemoveFiles(m_context)); + AddTask(new TaskDbUpdate(m_context)); +} + +WidgetHandle JobWidgetUninstall::getRemovedWidgetHandle() const +{ + return m_context.widgetHandle; +} + +bool JobWidgetUninstall::getRemoveStartedFlag() const +{ + return m_context.removeStarted; +} + +bool JobWidgetUninstall::getRemoveFinishedFlag() const +{ + return m_context.removeFinished; +} + +void JobWidgetUninstall::SendProgress() +{ + if (!getRemoveStartedFlag() || + (getRemoveStartedFlag() && getRemoveFinishedFlag())) { + if (NULL != getInstallerStruct().progressCallback) { + LogDebug("Call widget uninstall progressCallback"); + getInstallerStruct().progressCallback( + getInstallerStruct().userParam, + GetProgressPercent(), GetProgressDescription()); + } + } +} + +void JobWidgetUninstall::SendFinishedSuccess() +{ + LogDebug("Call widget uninstall success finishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + getRemovedWidgetHandle(),Exceptions::Success); +} + +void JobWidgetUninstall::SendFinishedFailure() +{ + LogError("Error in uninstallation step: " << m_exceptionCaught); + LogError("Message: " << m_exceptionMessage); + + LogDebug("Call widget uninstall failure finishedCallback"); + getInstallerStruct().finishedCallback(getInstallerStruct().userParam, + getRemovedWidgetHandle(), m_exceptionCaught); //TODO + LogDebug("[JobWidgetUninstall] Asynchronous failure callback status sent"); +} + +void JobWidgetUninstall::SaveExceptionData(const Jobs::JobExceptionBase &e) +{ + m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam()); + m_exceptionMessage = e.GetMessage(); +} +} //namespace WidgetUninstall +} //namespace Jobs diff --git a/src/jobs/widget_uninstall/job_widget_uninstall.h b/src/jobs/widget_uninstall/job_widget_uninstall.h new file mode 100644 index 0000000..ddf3b4e --- /dev/null +++ b/src/jobs/widget_uninstall/job_widget_uninstall.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file job_widet_uninstall.h + * @brief Uninstaller header file. + * @author Radoslaw Wicik r.wicik@samsung.com + */ + +#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_JOB_WIDGET_UNINSTALL_H_ +#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_JOB_WIDGET_UNINSTALL_H_ + +#include <job.h> +#include <job_base.h> +#include <widget_uninstall/widget_uninstaller_struct.h> +#include <widget_uninstall/uninstaller_context.h> + +namespace Jobs { +namespace WidgetUninstall { +class JobWidgetUninstall : + public Job, + public JobProgressBase<UninstallerContext::UninstallStep, + UninstallerContext::UNINSTALL_END>, + public JobContextBase<WidgetUninstallationStruct> //TODO typedef +{ + private: + UninstallerContext m_context; + + //TODO move it to base class of all jobs + Exceptions::Type m_exceptionCaught; + std::string m_exceptionMessage; + + public: + /** + * @brief Uninstaller must to know which widget to uninstall. + * + * @param[in] const int& widget_id - wdget to uninstall + */ + JobWidgetUninstall(WidgetHandle widgetHandle, + const WidgetUninstallationStruct& uninstallerStruct); + + WidgetHandle getRemovedWidgetHandle() const; + bool getRemoveStartedFlag() const; + bool getRemoveFinishedFlag() const; + + void SendProgress(); + void SendFinishedSuccess(); + void SendFinishedFailure(); + void SaveExceptionData(const Jobs::JobExceptionBase &e); +}; +} //namespace WidgetUninstall +} //namespace Jobs + +#endif // WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_JOB_WIDGET_UNINSTALL_H_ diff --git a/src/jobs/widget_uninstall/task_check.cpp b/src/jobs/widget_uninstall/task_check.cpp new file mode 100644 index 0000000..e1eb8d4 --- /dev/null +++ b/src/jobs/widget_uninstall/task_check.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_check.cpp + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @version 1.0 + * @brief Header file for widget uninstall task check + */ +#include <dpl/sstream.h> +#include <widget_uninstall/task_check.h> +#include <widget_uninstall/job_widget_uninstall.h> +#include <widget_uninstall/uninstaller_context.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <aul.h> + +namespace Jobs { +namespace WidgetUninstall { +TaskCheck::TaskCheck(UninstallerContext& context) : + DPL::TaskDecl<TaskCheck>(this), + m_context(context) +{ + AddStep(&TaskCheck::StepUninstallPreCheck); +} + +TaskCheck::~TaskCheck() +{ +} + +void TaskCheck::StepUninstallPreCheck() +{ + LogInfo("Uninstall check for widget Handle: " << m_context.widgetHandle); + //check if deferred + //TODO if widget to be updated, then remove it from Deferred list? + + DPL::OptionalString pkgName = + WrtDB::WidgetDAO(m_context.widgetHandle).getPkgname(); + + LogInfo("Widget model exists. Pkg name: " << pkgName); + if (aul_app_is_running(DPL::ToUTF8String(*pkgName).c_str())) { + LogError("Widget is not stopped. Cannot uninstall!"); + //TODO different error + ThrowMsg(Exceptions::AlreadyUninstalling, + "Widget is not stopped. Cannot uninstall!"); + //TODO or defer uninstall? + } + + LogInfo("Widget Can be uninstalled. Handle : " << m_context.widgetHandle); + m_context.job->UpdateProgress(UninstallerContext::UNINSTALL_CHECK, + "Uninstall pre-checking Finished"); +} + +} //namespace WidgetUninstall +} //namespace Jobs diff --git a/src/jobs/widget_uninstall/task_check.h b/src/jobs/widget_uninstall/task_check.h new file mode 100644 index 0000000..4207726 --- /dev/null +++ b/src/jobs/widget_uninstall/task_check.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_check.h + * @author Pawel Sikorski(p.sikorski@samsung.com) + * @version 1.0 + * @brief Header file for widget uninstall task check + */ + +#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_CHECK_H_ +#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_CHECK_H_ + +#include <dpl/task.h> + +struct UninstallerContext; //forward declaration +class WidgetModel; + +namespace Jobs { +namespace WidgetUninstall { +class TaskCheck : + public DPL::TaskDecl<TaskCheck> +{ + private: + //context + UninstallerContext& m_context; + + //steps + void StepUninstallPreCheck(); + + public: + TaskCheck(UninstallerContext& context); + virtual ~TaskCheck(); +}; +} //namespace WidgetUninstall +} //namespace Jobs + +#endif /* WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_CHECK_H_ */ diff --git a/src/jobs/widget_uninstall/task_db_update.cpp b/src/jobs/widget_uninstall/task_db_update.cpp new file mode 100644 index 0000000..a7db085 --- /dev/null +++ b/src/jobs/widget_uninstall/task_db_update.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_db_update.cpp + * @author Lukasz Wrzosek(l.wrzosek@samsung.com) + * @version 1.0 + * @brief Implementation file for uninstaller task database updating + */ + +#include <widget_uninstall/task_db_update.h> +#include <widget_uninstall/job_widget_uninstall.h> +#include <widget_uninstall/widget_uninstall_errors.h> + +#include <dpl/assert.h> + +using namespace WrtDB; + +namespace Jobs { +namespace WidgetUninstall { +TaskDbUpdate::TaskDbUpdate(UninstallerContext& context) : + DPL::TaskDecl<TaskDbUpdate>(this), + m_context(context) +{ + AddStep(&TaskDbUpdate::StepDbUpdate); +} + +TaskDbUpdate::~TaskDbUpdate() +{ +} + +void TaskDbUpdate::StepDbUpdate() +{ + Try + { + WidgetDAO::unregisterWidget(m_context.widgetHandle); + + LogDebug("Unregistered widget successfully!"); + } + Catch(DPL::DB::SqlConnection::Exception::Base) + { + LogDebug("Failed to handle StepDbUpdate!"); + ReThrowMsg(Exceptions::DatabaseFailure, + "Failed to handle StepDbUpdate!"); + } + + m_context.job->UpdateProgress( + UninstallerContext::UNINSTALL_DB_UPDATE, + "Widget DB Update Finished"); +} +} //namespace WidgetUninstall +} //namespace Jobs diff --git a/src/jobs/widget_uninstall/task_db_update.h b/src/jobs/widget_uninstall/task_db_update.h new file mode 100644 index 0000000..93c4ff2 --- /dev/null +++ b/src/jobs/widget_uninstall/task_db_update.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_db_update.h + * @author Lukasz Wrzosek(l.wrzosek@samsung.com) + * @version 1.0 + * @brief Header file for uninstaller task database updating + */ + +#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DB_UPDATE_H_ +#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DB_UPDATE_H_ + +#include <dpl/task.h> +#include <dpl/wrt-dao-rw/widget_dao.h> //TODO not needed here + +#include <widget_uninstall/uninstaller_context.h> //todo forward decl + +#include <string> + +namespace Jobs { +namespace WidgetUninstall { +class TaskDbUpdate : + public DPL::TaskDecl<TaskDbUpdate> +{ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, DbStepFailed) + }; + + UninstallerContext& m_context; + + private: + void StepDbUpdate(); + + public: + TaskDbUpdate(UninstallerContext& context); + virtual ~TaskDbUpdate(); +}; +} //namespace WidgetUninstall +} //namespace Jobs + +#endif // WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DB_UPDATE_H_ diff --git a/src/jobs/widget_uninstall/task_remove_files.cpp b/src/jobs/widget_uninstall/task_remove_files.cpp new file mode 100644 index 0000000..efde73b --- /dev/null +++ b/src/jobs/widget_uninstall/task_remove_files.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_remove_files.cpp + * @author Lukasz Wrzosek(l.wrzosek@samsung.com) + * @version 1.0 + * @brief Implementation file for uninstaller task for removing widget files + */ + +#include <widget_uninstall/task_remove_files.h> +#include <widget_uninstall/job_widget_uninstall.h> +#include <dpl/wrt-dao-ro/widget_config.h> + +#include <errno.h> +#include <dpl/assert.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> +#include <dpl/utils/wrt_utility.h> + +namespace Jobs { +namespace WidgetUninstall { + +using namespace WrtDB; + +void TaskRemoveFiles::ReadDir(const std::string& path, + std::list<std::string>& filesList) +{ + LogInfo("Reading directory " << path); + DIR* dir = NULL; + struct dirent* ptr = NULL; + dir = opendir(path.c_str()); + std::string delim = ""; + + // adding / for path to directory to build a proper path to file under directory + if (path[path.size() - 1] != '/') { + delim = "/"; + } + + if (dir) { + while ((ptr = readdir(dir)) != NULL) { + if ((!strcmp(ptr->d_name, ".")) || (!strcmp(ptr->d_name, ".."))) { + LogPedantic("Omiting " << ptr->d_name); + continue; + } + std::string childPath = path + delim + ptr->d_name; + + struct stat st; + if (0 != lstat(childPath.c_str(), &st)) { + switch (errno) { + case EACCES: + LogWarning( + "EACCESS Error occured during lstat with path: " << + childPath); + continue; + case EBADF: + LogWarning( + "EBADF Error occured during lstat with path: " << + childPath); + continue; + case ENOENT: + LogWarning( + "ENOENT Error occured during lstat with path: " << + childPath); + continue; + case ENOTDIR: + LogWarning( + "ENOTDIR Error occured during lstat with path: " << + childPath); + continue; + default: + LogWarning( + "Unknown Error occured during lstat with path: " << + childPath); + continue; + } + } else { + if (S_ISDIR(st.st_mode)) { + LogPedantic( + "Calling ReadDir in recursive way " << childPath); + ReadDir(childPath, filesList); + } else if (S_ISREG(st.st_mode) || + S_ISCHR(st.st_mode) || + S_ISBLK(st.st_mode) || + S_ISFIFO(st.st_mode) || + S_ISLNK(st.st_mode) || + S_ISSOCK(st.st_mode)) { + LogPedantic("Adding to list " << childPath); + filesList.push_front(childPath); + } else { + LogWarning("Uknown file type ??"); + } + } + } + closedir(dir); + } else if (errno == ENOTDIR) { + LogDebug("Adding to list " << path); + filesList.push_front(path); + } else { + LogWarning("Unknown error"); + } +} + +TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) : + DPL::TaskDecl<TaskRemoveFiles>(this), + m_context(context) +{ + AddStep(&TaskRemoveFiles::StepPrepare); + AddStep(&TaskRemoveFiles::StepRemoveOneFile); + AddStep(&TaskRemoveFiles::StepRemoveDirectories); + AddStep(&TaskRemoveFiles::StepRemoveDesktop); + AddStep(&TaskRemoveFiles::StepRemoveFinished); +} + +TaskRemoveFiles::~TaskRemoveFiles() +{ +} + +void TaskRemoveFiles::StepPrepare() +{ + LogInfo("StepPrepare started"); + + std::ostringstream widgetDir; + + DPL::OptionalString pkgname = WidgetDAO(m_context.widgetHandle).getPkgname(); + widgetDir << GlobalConfig::GetUserInstalledWidgetPath() << "/"; + widgetDir << pkgname << "/"; + + uninstRootDir = widgetDir.str(); + ReadDir(uninstRootDir, filesList); + + LogInfo("StepPrepare finished"); + + m_context.job->UpdateProgress( + UninstallerContext::UNINSTALL_REMOVE_PREPARE, + "Widget remove prepare Finished"); + m_context.removeStarted = true; +} + +void TaskRemoveFiles::StepRemoveOneFile() +{ + if (filesList.size() > 0) { + LogDebug("Removing " << filesList.front()); + if (0 != unlink(filesList.front().c_str())) { + LogWarning("Failed to remove file" << filesList.front()); + } + filesList.pop_front(); + SwitchToStep(&TaskRemoveFiles::StepRemoveOneFile); + } else { + m_context.removeFinished = true; + } + + m_context.job->UpdateProgress( + UninstallerContext::UNINSTALL_REMOVE_ONEFILE, + "Widget remove onefile Finished"); +} + +void TaskRemoveFiles::StepRemoveDirectories() +{ + using namespace WrtDB; + LogInfo("StepRemoveDirectories started"); + + if (!_WrtUtilRemoveDir(uninstRootDir.c_str())) { + LogWarning("Failed to remove directory" << uninstRootDir.c_str()); + } + LogInfo("StepRemoveDirectories finished"); + + m_context.job->UpdateProgress( + UninstallerContext::UNINSTALL_REMOVE_DIRECTORIES, + "Widget remove directories Finished"); +} + +void TaskRemoveFiles::StepRemoveFinished() +{ + LogInfo("StepRemoveFinished finished"); + + m_context.job->UpdateProgress( + UninstallerContext::UNINSTALL_REMOVE_FINISHED, + "Widget remove steps Finished"); +} + +void TaskRemoveFiles::StepRemoveDesktop() +{ + std::ostringstream desktopFile; + + DPL::OptionalString pkgname = WidgetDAO(m_context.widgetHandle).getPkgname(); + desktopFile << GlobalConfig::GetUserWidgetDesktopPath() << "/"; + desktopFile << pkgname << ".desktop"; + + unlink(desktopFile.str().c_str()); + + m_context.job->UpdateProgress( + UninstallerContext::UNINSTALL_REMOVE_DESKTOP, + "Widget remove desktop Finished"); +} +} //namespace WidgetUninstall +} //namespace Jobs diff --git a/src/jobs/widget_uninstall/task_remove_files.h b/src/jobs/widget_uninstall/task_remove_files.h new file mode 100644 index 0000000..393732b --- /dev/null +++ b/src/jobs/widget_uninstall/task_remove_files.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file task_remove_files.h + * @author Lukasz Wrzosek(l.wrzosek@samsung.com) + * @version 1.0 + * @brief Header file for uninstaller task remove files + */ + +#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_REMOVE_FILES_H_ +#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_REMOVE_FILES_H_ + +#include <dpl/task.h> +#include <dpl/wrt-dao-rw/widget_dao.h> //todo not needed here + +#include <widget_uninstall/uninstaller_context.h> //TODO forward decl + +#include <string> + +namespace Jobs { +namespace WidgetUninstall { +class TaskRemoveFiles : + public DPL::TaskDecl<TaskRemoveFiles> +{ + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, RemoveFilesFailed) + }; + + UninstallerContext& m_context; + std::list<std::string> filesList; + std::string uninstRootDir; + + static void ReadDir(const std::string& path, + std::list<std::string>& filesList); + + private: + void StepPrepare(); + void StepRemoveOneFile(); + void StepRemoveDirectories(); + void StepRemoveFinished(); + void StepRemoveDesktop(); + + public: + explicit TaskRemoveFiles(UninstallerContext& context); + virtual ~TaskRemoveFiles(); +}; +} //namespace WidgetUninstall +} //namespace Jobs + +#endif // WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_REMOVE_FILES_H_ diff --git a/src/jobs/widget_uninstall/task_smack.cpp b/src/jobs/widget_uninstall/task_smack.cpp new file mode 100644 index 0000000..0d529ca --- /dev/null +++ b/src/jobs/widget_uninstall/task_smack.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_smack.cpp + * @author Piotr Kozbial (p.kozbial@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task smack + */ + +#include <widget_uninstall/task_smack.h> +#include <widget_uninstall/uninstaller_context.h> +#include <dpl/optional_typedefs.h> +#ifdef WRT_SMACK_ENABLED +#include <privilege-control.h> +#endif + +namespace Jobs { +namespace WidgetUninstall { +TaskSmack::TaskSmack(UninstallerContext& context) : + DPL::TaskDecl<TaskSmack>(this), + m_context(context) +{ + AddStep(&TaskSmack::Step); +} + +void TaskSmack::Step() +{ + LogInfo("------------------------> SMACK: Jobs::WidgetUninstall::TaskSmack::Step()"); +#ifdef WRT_SMACK_ENABLED + try { + WrtDB::WidgetDAOReadOnly dao(m_context.widgetHandle); + DPL::OptionalString pkgName = dao.getPkgname(); + Assert(!pkgName.IsNull() && "widget doesn't have a pkg name"); + const char *devCap = ""; + int result = handle_access_control_conf_forWAC( + DPL::ToUTF8String(*pkgName).c_str(), + NULL, + OPERATION_UNINSTALL); + Assert(result==PC_OPERATION_SUCCESS && "access control setup failed"); + } catch (WrtDB::WidgetDAOReadOnly::Exception) { + Assert(false && "can't access widget data"); + } +#endif +} + +} //namespace WidgetUninstall +} //namespace Jobs diff --git a/src/jobs/widget_uninstall/task_smack.h b/src/jobs/widget_uninstall/task_smack.h new file mode 100644 index 0000000..35a0355 --- /dev/null +++ b/src/jobs/widget_uninstall/task_smack.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file task_smack.h + * @author Piotr Kozbial (p.kozbial@samsung.com) + * @version 1.0 + * @brief Header file for uninstaller task smack + */ +#ifndef INSTALLER_CORE_JOS_WIDGET_UNINSTALL_TASK_SMACK_H +#define INSTALLER_CORE_JOS_WIDGET_UNINSTALL_TASK_SMACK_H + +#include <dpl/task.h> + +class UninstallerContext; + +namespace Jobs { +namespace WidgetUninstall { +class TaskSmack: + public DPL::TaskDecl<TaskSmack> +{ + private: + UninstallerContext& m_context; + + void Step(); + + public: + TaskSmack(UninstallerContext& context); +}; +} //namespace WidgetUninstall +} //namespace Jobs + +#endif /* INSTALLER_CORE_JOS_WIDGET_UNINSTALL_TASK_SMACK_H */ diff --git a/src/jobs/widget_uninstall/uninstaller_context.h b/src/jobs/widget_uninstall/uninstaller_context.h new file mode 100644 index 0000000..9317654 --- /dev/null +++ b/src/jobs/widget_uninstall/uninstaller_context.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file uninstaller_context.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version + * @brief Definition file of installer tasks data structures + */ + +#ifndef WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_ +#define WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_ + +#include <string> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <widget_uninstall/widget_uninstaller_struct.h> + +namespace Jobs { +namespace WidgetUninstall { +class JobWidgetUninstall; +} //namespace WidgetUninstall +} //namespace Jobs + +struct UninstallerContext +{ + enum UninstallStep + { + UNINSTALL_START, + UNINSTALL_CHECK, + UNINSTALL_DB_UPDATE, + UNINSTALL_REMOVE_PREPARE, + UNINSTALL_REMOVE_ONEFILE, + UNINSTALL_REMOVE_DIRECTORIES, + UNINSTALL_REMOVE_FINISHED, + UNINSTALL_REMOVE_DESKTOP, + UNINSTALL_END + }; + + WidgetHandle widgetHandle; + + ///< flag that indicates whether installer starts + //to remove files.rStruct; + bool removeStarted; + ///< flag that indicates whether installer finishes + //to remove files completely. + bool removeFinished; + UninstallStep uninstallStep; ///< current step of installation + Jobs::WidgetUninstall::JobWidgetUninstall *job; +}; + +#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_ diff --git a/src/jobs/widget_uninstall/widget_uninstall_errors.h b/src/jobs/widget_uninstall/widget_uninstall_errors.h new file mode 100644 index 0000000..91173a0 --- /dev/null +++ b/src/jobs/widget_uninstall/widget_uninstall_errors.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file widget_uninstall_errors.h + * @author Pawel Sikorski (p.sikorski@samgsung.com) + * @version + * @brief + */ + +#ifndef WIDGET_UNINSTALL_ERRORS_H_ +#define WIDGET_UNINSTALL_ERRORS_H_ + +#include <job_exception_base.h> + +namespace Jobs { +namespace WidgetUninstall { +namespace Exceptions { +enum Type +{ + Success, + + ErrorWidgetDoesNotExist, + ErrorFactoryWidget, + ErrorAlreadyUninstalling, + ErrorDatabaseFailure, + ErrorUnknown +}; + +DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown) + +DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorDatabaseFailure) +DECLARE_JOB_EXCEPTION(Base, FactoryWidget, ErrorFactoryWidget) +DECLARE_JOB_EXCEPTION(Base, AlreadyUninstalling, ErrorAlreadyUninstalling) +DECLARE_JOB_EXCEPTION(Base, WidgetNotExist, ErrorWidgetDoesNotExist) +} //namespace +} //namespace +} //namespace + +#endif /* WIDGET_UNINSTALL_ERRORS_H_ */ diff --git a/src/jobs/widget_uninstall/widget_uninstaller_struct.h b/src/jobs/widget_uninstall/widget_uninstaller_struct.h new file mode 100644 index 0000000..fb7a152 --- /dev/null +++ b/src/jobs/widget_uninstall/widget_uninstaller_struct.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file widget_uninstaller_struct.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Implementation file for widget installer struct + */ +#ifndef WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ +#define WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ + +//SYSTEM INCLUDES +#include <dpl/assert.h> + +//WRT INCLUDES +#include <job_base.h> +#include <wrt_common_types.h> +#include <widget_uninstall/widget_uninstall_errors.h> + +//Widget Uninstaller typedefs +typedef void (*UninstallerFinishedCallback)( + void *userParam, + WidgetHandle, + Jobs::WidgetUninstall::Exceptions::Type); + +typedef void (*UninstallerProgressCallback)( + void *userParam, + ProgressPercent percent, + const ProgressDescription &description); + +//UninstallationStruct +typedef Jobs::JobCallbacksBase<UninstallerFinishedCallback, + UninstallerProgressCallback> +WidgetUninstallationStruct; + +#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ diff --git a/src/logic/installer_controller.cpp b/src/logic/installer_controller.cpp new file mode 100644 index 0000000..8009b98 --- /dev/null +++ b/src/logic/installer_controller.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "installer_controller.h" +#include <dpl/log/log.h> +#include <dpl/singleton_impl.h> +IMPLEMENT_SINGLETON(InstallerController) + +InstallerController::InstallerController() +{ +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::InstallWidgetEvent &event) +{ + std::string zipFileName = event.GetArg0(); + WidgetInstallationStruct installerStruct = event.GetArg1(); + Jobs::JobHandle handle = + m_installerLogic.InstallWidget(zipFileName, installerStruct); + + //TODO return handle to API + (void)handle; +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::InstallPluginEvent &event) +{ + std::string dirName = event.GetArg0(); + PluginInstallerStruct installerStruct = event.GetArg1(); + + Jobs::JobHandle handle = + m_installerLogic.InstallPlugin(dirName, installerStruct); + + //TODO return handle to API + (void)handle; +} + +void InstallerController::OnEventReceived(const InstallerControllerEvents:: + InstallPluginGeolocationEvent &event) +{ + PluginInstallerStruct installerStruct = event.GetArg0(); + + InstallerLogic::InstallPluginGeolocation(installerStruct); +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::UninstallWidgetEvent &event) +{ + WidgetHandle widgetHandle = event.GetArg0(); + WidgetUninstallationStruct uninstallerStruct = event.GetArg1(); + Jobs::JobHandle handle = + m_installerLogic.UninstallWidget(widgetHandle, uninstallerStruct); + + //TODO return handle to API + (void)handle; +} + +Eina_Bool InstallerController::AddNextStep(void *data) +{ + Jobs::Job* model = static_cast<Jobs::Job *>(data); + CONTROLLER_POST_EVENT(InstallerController, + InstallerControllerEvents::NextStepEvent(model)); + + return ECORE_CALLBACK_CANCEL; +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::NextStepEvent &event) +{ + Jobs::Job* model = event.GetArg0(); + Assert(model != NULL); + + if (m_installerLogic.NextStep(model)) { + ecore_idler_add(AddNextStep, model); + } +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::InstallDeferredWidgetPackagesEvent & + event) +{ + (void)event; + m_installerLogic.InstallDeferredWidgetPackages(); +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::InitializeEvent & /*event*/) +{ + m_installerLogic.Initialize(); +} + +void InstallerController::OnEventReceived( + const InstallerControllerEvents::TerminateEvent & /*event*/) +{ + m_installerLogic.Terminate(); +} diff --git a/src/logic/installer_controller.h b/src/logic/installer_controller.h new file mode 100644 index 0000000..8ce43fc --- /dev/null +++ b/src/logic/installer_controller.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 WRT_SRC_INSTALLER_CORE_INSTALLER_CONTROLLER_H_ +#define WRT_SRC_INSTALLER_CORE_INSTALLER_CONTROLLER_H_ + +#include <dpl/singleton.h> +#include <dpl/event/controller.h> +#include <dpl/generic_event.h> +#include <string> +#include <map> +#include <dpl/task_list.h> +#include <dpl/task.h> +#include <dpl/type_list.h> +#include <widget_install/widget_installer_struct.h> +#include <installer_logic.h> +#include <job.h> + +/** + * @brief holds events send to InstallControler + */ +namespace InstallerControllerEvents { +/** + * @brief Event for inicieting instalation process. + * + * This event holds std::string witch should be path to widget package + */ +DECLARE_GENERIC_EVENT_2(InstallWidgetEvent, + std::string, + WidgetInstallationStruct) // (zipFileName, installerStruct) + +/** + * @brief Event for iniciating plugin instalation process. + * This event holds std::string witch should be path to plugin directory + * and PluginInstallerStruct which contain + * StatusCallack, progressCallback and private data for callbacks + */ +DECLARE_GENERIC_EVENT_2(InstallPluginEvent, std::string, PluginInstallerStruct) + +/** + * @brief Event for indiciating W3C Geolocation plugin instalation process. + */ +DECLARE_GENERIC_EVENT_1(InstallPluginGeolocationEvent, PluginInstallerStruct) // + +/** + * @brief Event for inicietig widget uninstallation. + * + * WidgetHandler is used to point witch widget shuld be uninstalled + */ +DECLARE_GENERIC_EVENT_2(UninstallWidgetEvent, + WidgetHandle, + WidgetUninstallationStruct) + +/** + * @brief Event for pushing installation process forward. + */ +DECLARE_GENERIC_EVENT_1(NextStepEvent, Jobs::Job *) + +DECLARE_GENERIC_EVENT_0(InstallDeferredWidgetPackagesEvent) + +DECLARE_GENERIC_EVENT_0(InitializeEvent) +DECLARE_GENERIC_EVENT_0(TerminateEvent) + +} // namespace InstallerEvents + +/** + * @brief Controls Widget installation + * + * Main Controler of wiget installation/uninstallation, this is also used + * for pushing forward each of processes. + * It waits for three events: + * <ul> + * <li>InstallWidgetEvent</li> + * <li>UninstallWidgetEvent</li> + * <li>NextStepEvent</li> + * </ul> + */ + +typedef DPL::TypeListDecl< + InstallerControllerEvents::InstallWidgetEvent, + InstallerControllerEvents::InstallPluginEvent, + InstallerControllerEvents::InstallPluginGeolocationEvent, + InstallerControllerEvents::UninstallWidgetEvent, + InstallerControllerEvents::NextStepEvent, + InstallerControllerEvents::InstallDeferredWidgetPackagesEvent, + InstallerControllerEvents::InitializeEvent, + InstallerControllerEvents::TerminateEvent>::Type +InstallerControllerEventsSet; + +class InstallerController : public DPL::Event::Controller<InstallerControllerEventsSet> +{ + protected: + /** + * @brief Executed on InstallWidgetEvent received. + */ + virtual void OnEventReceived( + const InstallerControllerEvents::InstallWidgetEvent &event); + + /** + * @brief Executed on InstallPluginEvent received. + */ + virtual void OnEventReceived( + const InstallerControllerEvents::InstallPluginEvent &event); + + /** + * @brief Executed on InstallPluginEvent received. + */ + virtual void OnEventReceived( + const InstallerControllerEvents::InstallPluginGeolocationEvent + &event); + + /** + * @brief Executed on UninstallWidgetEvent received. + */ + virtual void OnEventReceived( + const InstallerControllerEvents::UninstallWidgetEvent &event); + /** + * @brief Executed on NextStepEvent received. + */ + virtual void OnEventReceived( + const InstallerControllerEvents::NextStepEvent &event); + + virtual void OnEventReceived( + const InstallerControllerEvents::InstallDeferredWidgetPackagesEvent + &event); + + virtual void OnEventReceived( + const InstallerControllerEvents::InitializeEvent &event); + virtual void OnEventReceived( + const InstallerControllerEvents::TerminateEvent &event); + + private: + // Embedded logic + InstallerLogic m_installerLogic; + + InstallerController(); + + static Eina_Bool AddNextStep(void *data); + + friend class DPL::Singleton<InstallerController>; +}; + +typedef DPL::Singleton<InstallerController> InstallerControllerSingleton; + +#endif // INSTALLER_CONTROLLER_H diff --git a/src/logic/installer_logic.cpp b/src/logic/installer_logic.cpp new file mode 100644 index 0000000..4cb7eb0 --- /dev/null +++ b/src/logic/installer_logic.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <installer_logic.h> +#include <installer_controller.h> +#include <dpl/string.h> +#include <dpl/foreach.h> +//#include <plugin_logic.h> +#include <dpl/wrt-dao-rw/feature_dao.h> +#include <dpl/wrt-dao-rw/plugin_dao.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <widget_install/job_widget_install.h> +#include <widget_uninstall/job_widget_uninstall.h> +#include <plugin_install/job_plugin_install.h> +#include <job_exception_base.h> +#include <plugin_install/plugin_objects.h> + +using namespace WrtDB; + +InstallerLogic::InstallerLogic() : + m_NextHandle(0) +{ +} + +InstallerLogic::~InstallerLogic() +{ + Assert(m_jobs.empty() && "There are still running jobs"); + //FIXME what should be done here? +} + +void InstallerLogic::Initialize() +{ + LogDebug("Done"); +} + +void InstallerLogic::Terminate() +{ + //TODO how to delete, if it is still running, paused and so on + FOREACH(it, m_jobs) + { + it->second->SetPaused(true); //FIXME this is not enough! + } + + LogDebug("Done"); +} + +Jobs::JobHandle InstallerLogic::AddAndStartJob(Jobs::Job *job) +{ + Jobs::JobHandle handle = GetNewJobHandle(); + job->SetJobHandle(handle); + + m_jobs.insert(std::make_pair(handle, job)); + + //Start job + CONTROLLER_POST_EVENT(InstallerController, + InstallerControllerEvents::NextStepEvent(job)); + + return handle; +} + +//InstallWidget, UninstallWidget InstallPlugin method are almost the same +// But each Job has different constructor, so creating new Job is specific +// i.e. widgetHandle, path etc... +Jobs::JobHandle InstallerLogic::InstallWidget(std::string const & widgetPath, + const WidgetInstallationStruct &installerStruct) +{ + LogDebug("New Widget Installation:"); + + Jobs::Job *job = + new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, installerStruct); + + return AddAndStartJob(job); +} + +Jobs::JobHandle InstallerLogic::UninstallWidget(WidgetHandle widgetHandle, + const WidgetUninstallationStruct &uninstallerStruct) +{ + LogDebug("New Widget Uninstallation"); + + Jobs::Job *job = + new Jobs::WidgetUninstall::JobWidgetUninstall(widgetHandle, + uninstallerStruct); + + return AddAndStartJob(job); +} + +Jobs::JobHandle InstallerLogic::InstallPlugin(std::string const & pluginPath, + const PluginInstallerStruct &installerStruct) +{ + LogDebug("New Plugin Installation"); + + Jobs::Job *job = + new Jobs::PluginInstall::JobPluginInstall(pluginPath, installerStruct); + + return AddAndStartJob(job); +} + +#define TRANSLATE_JOB_EXCEPTION() \ + _rethrown_exception.getParam() +#define TRANSLATE_JOB_MESSAGE() \ + _rethrown_exception.GetMessage() + +bool InstallerLogic::NextStep(Jobs::Job *job) +{ + Try { + bool stepSucceded = job->NextStep(); + + if (stepSucceded) { + job->SendProgress(); + + return !job->IsPaused(); + } + + if (!job->GetUndoType()) { + //job successfully finished + + //send finished callback + job->SendFinishedSuccess(); + + switch (job->GetInstallationType()) { + case Jobs::PluginInstallation: + //todo move it somewhere + InstallWaitingPlugins(); + break; + default: //because of warning + break; + } + } else { + //job abort process completed + job->SendFinishedFailure(); + } + + //clean job + m_jobs.erase(job->GetJobHandle()); + delete job; + + return false; + } + catch (Jobs::JobExceptionBase &exc) { + //start revert job + LogInfo("Exception occured: " << exc.getParam() << + ". Reverting job..."); + bool hasAbortSteps = job->Abort(); + job->SetUndoType(true); + job->SaveExceptionData(exc); + + if (!hasAbortSteps) { + //no AbortSteps + job->SendFinishedFailure(); + + //clean job + m_jobs.erase(job->GetJobHandle()); + delete job; + } + return hasAbortSteps; + } +} + +//TODO this should be moved somewhere...when it should take place? after widget +//is closing? +void InstallerLogic::InstallDeferredWidgetPackages() +{ + LogWarning("Not implemented"); + // LogInfo("Installing deferred widget packages..."); + // + // WidgetPackageList packages = GlobalDAO::GetDefferedWidgetPackageInstallationList(); + // + // LogInfo(packages.size() << " widget package(s) to install"); + // + // // Make a copy of widget packages to install, because some + // // widget packages may still fail because they are running + // m_packagesToInstall = packages; + // + // // Start processing + // InstallSingleDeferredPackage(); +} + +void InstallerLogic::InstallSingleDeferredPackage() +{ + LogWarning("Not implemented"); + // if (m_packagesToInstall.empty()) + // return; + // + // // Take single package + // DPL::String widgetPackage = m_packagesToInstall.front(); + // m_packagesToInstall.pop_front(); + // + // // Remove it from DB + // GlobalDAO::RemoveDefferedWidgetPackageInstallation(widgetPackage); + // + // // Begin installation + // LogInfo("Installing deferred widget package: " << widgetPackage); + // + // // Post installation + // CONTROLLER_POST_EVENT( + // InstallerController, InstallerControllerEvents::InstallWidgetEvent( + // DPL::ToUTF8String(widgetPackage).c_str(), WidgetInstallationStruct( + // &DummyInstallCallback, &DummyProgressCallback, NULL, + // WidgetUpdateMode::PolicyWac))); +} + +void InstallerLogic::InstallPluginGeolocation( + const PluginInstallerStruct &installerStruct) +{ + FeatureDAO::RegisterStrangeFeature( + std::string(GlobalConfig::GetW3CGeolocationFeatureName())); + + LogDebug("Call plugins installer FinishedCallback"); + installerStruct.finishedCallback(installerStruct.userParam, + Jobs::PluginInstall::Exceptions::Success); +} + +void InstallerLogic::InstallWaitingPlugins() +{ + PluginHandleSetPtr waitingPlugins; + + waitingPlugins = + PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING); + + FOREACH(it, *waitingPlugins) + { + resolvePluginDependencies(*it); + } +} + +bool InstallerLogic::resolvePluginDependencies(PluginHandle handle) +{ + PluginHandleSetPtr dependencies(new PluginHandleSet); + + PluginObjects::ObjectsPtr requiredObjects = + PluginDAO::getRequiredObjectsForPluginHandle(handle); + + PluginHandle depHandle = + Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE; + + FOREACH(requiredObject, *requiredObjects) + { + depHandle = + PluginDAO::getPluginHandleForImplementedObject(*requiredObject); + + if (depHandle == + Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE) { + LogError("Library implementing: " << + *requiredObject << " NOT FOUND"); + + //PluginDAO::SetPluginInstallationStatus(INSTALLATION_WAITING); + return false; + } + dependencies->insert(depHandle); + } + + PluginDAO::registerPluginLibrariesDependencies(handle, dependencies); + PluginDAO::setPluginInstallationStatus(handle, + PluginDAO::INSTALLATION_COMPLETED); + + return true; +} + diff --git a/src/logic/installer_logic.h b/src/logic/installer_logic.h new file mode 100644 index 0000000..db45295 --- /dev/null +++ b/src/logic/installer_logic.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 WRT_SRC_INSTALLER_CORE_INSTALLER_LOGIC_H_ +#define WRT_SRC_INSTALLER_CORE_INSTALLER_LOGIC_H_ + +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <dpl/wrt-dao-rw/global_dao.h> +#include <dpl/wrt-dao-ro/feature_model.h> +#include <widget_install/widget_installer_struct.h> +#include <widget_uninstall/widget_uninstaller_struct.h> +#include <plugin_install/plugin_installer_struct.h> +#include <job.h> + +//TODO create namespace + +class InstallerLogic +{ + typedef std::map<Jobs::JobHandle, Jobs::Job*> JobsContainer; + JobsContainer m_jobs; + + void InstallDeferredWidgetPackages(); + void InstallSingleDeferredPackage(); + + void InstallWaitingPlugins(); + bool resolvePluginDependencies(PluginHandle handle); + + Jobs::JobHandle m_NextHandle; + Jobs::JobHandle GetNewJobHandle() + { + return m_NextHandle++; + } + Jobs::JobHandle AddAndStartJob(Jobs::Job *job); + public: + virtual ~InstallerLogic(); + + void Initialize(); + + void Terminate(); + + Jobs::JobHandle InstallWidget(std::string const & widgetPath, + const WidgetInstallationStruct &installerStruct); + + Jobs::JobHandle UninstallWidget(WidgetHandle widgetHandle, + const WidgetUninstallationStruct &uninstallerStruct); + + Jobs::JobHandle InstallPlugin(std::string const & pluginPath, + const PluginInstallerStruct &installerStruct); + + bool NextStep(Jobs::Job* installModel); + + //TODO implement me + bool AbortJob(const Jobs::JobHandle & /*handle*/) + { + LogWarning("Not implemented"); + return true; + } + + static void InstallPluginGeolocation( + const PluginInstallerStruct &installerStruct); + private: + InstallerLogic(); + + friend class InstallerController; +}; + +#endif // INSTALLER_LOGIC_H diff --git a/src/misc/feature_logic.cpp b/src/misc/feature_logic.cpp new file mode 100644 index 0000000..a4e4bd3 --- /dev/null +++ b/src/misc/feature_logic.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "feature_logic.h" + +#include <list> + +#include <dpl/assert.h> +#include <dpl/noncopyable.h> +#include <dpl/string.h> +#include <dpl/foreach.h> + +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <dpl/wrt-dao-rw/global_dao.h> + +namespace Jobs { +namespace WidgetInstall { + +FeatureLogic::FeatureLogic(WidgetHandle handle) + : m_rejected(false) +{ + WrtDB::WidgetDAO widgetDao(handle); + WidgetFeatureSet featureSet = widgetDao.getFeaturesList(); + FOREACH(it, featureSet) { + WrtDB::DeviceCapabilitySet dcs = + WrtDB::GlobalDAO::GetDeviceCapability(it->name); + Feature feature(*it, dcs); + m_featureList.push_back(feature); + } + m_currentFeature = m_featureList.begin(); + + // ok we must set iterator on the first processable node + if (!isProcessable()) { + next(); + } +} + +bool FeatureLogic::isDone() const +{ + return m_currentFeature == m_featureList.end(); +} + +bool FeatureLogic::next() +{ + while (!isDone()) { + if (m_currentFeature->currentCap != m_currentFeature->devCapSet.end()) { + m_currentFeature->currentCap++; + } else { + ++m_currentFeature; + } + // we moved pointer + if (isProcessable()) { + return true; + } + } + return false; +} + + +void FeatureLogic::setAceResponse(bool allowed) +{ + Assert(isProcessable() && "Wrong usage"); + if (!allowed) { + m_currentFeature->rejected = true; + if (m_currentFeature->required) { + m_rejected = true; + } + } +} + +DPL::String FeatureLogic::getDevice() const +{ + return *(m_currentFeature->currentCap); +} + +bool FeatureLogic::isProcessable() const +{ + if (isDone()) { + return false; + } + + if (m_currentFeature->currentCap == m_currentFeature->devCapSet.end()) { + return false; + } + + return true; +} + +} // namespace WidgetInstall +} // namespace Jobs + diff --git a/src/misc/feature_logic.h b/src/misc/feature_logic.h new file mode 100644 index 0000000..550c123 --- /dev/null +++ b/src/misc/feature_logic.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 SRC_INSTALLER_MISC_FEATURE_LOGIC +#define SRC_INSTALLER_MISC_FEATURE_LOGIC + +#include <list> +#include <string> + +#include <dpl/assert.h> +#include <dpl/noncopyable.h> +#include <dpl/shared_ptr.h> + +#include <dpl/wrt-dao-ro/global_dao_read_only.h> +#include <wrt_common_types.h> + +namespace Jobs { +namespace WidgetInstall { + +class FeatureLogic : DPL::Noncopyable { + public: + + FeatureLogic(WidgetHandle handle); + + bool isDone() const; + + bool next(); + + void setAceResponse(bool allowed); + + DPL::String getDevice() const; + + bool isRejected(void) const + { + return m_rejected; + } + + private: + bool isProcessable() const; + + struct Feature : public WidgetFeature { + WrtDB::DeviceCapabilitySet devCapSet; + WrtDB::DeviceCapabilitySet::const_iterator currentCap; + bool rejected; + + Feature(const WidgetFeature &wf, const WrtDB::DeviceCapabilitySet &set) + : WidgetFeature(wf) + , devCapSet(set) + , rejected(false) + { + currentCap = devCapSet.begin(); + } + + explicit Feature(const Feature &second) : WidgetFeature(second) + { + devCapSet = second.devCapSet; + currentCap = devCapSet.find(*second.currentCap); + rejected = second.rejected; + } + private: + void operator=(const Feature &second) { + name = second.name; + devCapSet = second.devCapSet; + required = second.required; + rejected = second.rejected; + pluginId = second.pluginId; + params = second.params; + currentCap = devCapSet.find(*second.currentCap); + } + }; + typedef std::list<Feature> FeatureList; + + FeatureList m_featureList; + FeatureList::iterator m_currentFeature; + bool m_rejected; +}; + +typedef DPL::SharedPtr<FeatureLogic> FeatureLogicPtr; + +} // namespace WidgetInstall +} // namespace Jobs + +#endif // SRC_INSTALLER_MISC_FEATURE_LOGIC diff --git a/src/misc/wac_widget_id.cpp b/src/misc/wac_widget_id.cpp new file mode 100644 index 0000000..bc1f128 --- /dev/null +++ b/src/misc/wac_widget_id.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief + */ +#include "wac_widget_id.h" + +#include <memory> +#include <string> + +#include <dpl/log/log.h> +#include <dpl/string.h> + +#include <iri.h> +#include <vcore/ValidatorCommon.h> + +namespace { +const char *SCHEME_HTTP = "http"; +const char *SCHEME_HTTPS = "https"; +} + +WacWidgetId::WacWidgetId(const DPL::OptionalString &widgetId) : + m_schemaMatch(false) +{ + if (!widgetId.IsNull()) { + std::string wid = DPL::ToUTF8String(*widgetId); + parse(wid.c_str()); + } +} + +bool WacWidgetId::matchHost(const DPL::String &second) const +{ + LogDebug("m_schemaMatch is: " << m_schemaMatch); + if (!m_schemaMatch) { + return false; + } + + LogDebug("Matching DNS identity: " << m_host << + " " << DPL::ToUTF8String(second)); + + return m_host == DPL::ToUTF8String(second); +} + +void WacWidgetId::parse(const char *url) +{ + LogDebug("Widget id to parse: " << url); + + std::unique_ptr<iri_struct, std::function<void(iri_struct*)> > + iri(iri_parse(url), iri_destroy); + + if (!iri.get()) { + LogDebug("Error in parsing widget id."); + return; // m_schemaMatch == false; + } + + std::string scheme; + + if (iri.get()->scheme) { + scheme = iri.get()->scheme; + } else { + LogWarning("Error. No scheme in widget id."); + return; // m_schemaMatch == false; + } + + // should we support HTTP and HTTPS? wac says nothing + // std::transform(m_scheme.begin(), m_scheme.end(), m_scheme.begin(), tolower); + + // We only match "http" and "https" schemas + if ((scheme != SCHEME_HTTP) && (scheme != SCHEME_HTTPS)) { + LogWarning("Unknown scheme in widget id." << scheme); + return; // m_schemaMatch == false; + } else { + m_schemaMatch = true; + } + + if (iri.get()->host) { + m_host = iri.get()->host; + LogDebug("Host has been set to: " << m_host); + } + + // What to do when host is empty? No info in wac documentation. + + // Any post processing algorithm? No info in wac documentation. +} diff --git a/src/misc/wac_widget_id.h b/src/misc/wac_widget_id.h new file mode 100644 index 0000000..dba5f36 --- /dev/null +++ b/src/misc/wac_widget_id.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief + */ +#ifndef WRT_ENGINE_SRC_INSTALLER_CORE_MISC_WAC_WIDGET_ID_H +#define WRT_ENGINE_SRC_INSTALLER_CORE_MISC_WAC_WIDGET_ID_H + +#include <dpl/string.h> +#include <dpl/optional_typedefs.h> + +class WacWidgetId +{ + public: + explicit WacWidgetId(const DPL::OptionalString &widgetId); + bool matchHost(const DPL::String &second) const; + + private: + void parse(const char *url); + + bool m_schemaMatch; + std::string m_host; +}; + +#endif // WRT_ENGINE_SRC_INSTALLER_CORE_MISC_WAC_WIDGET_ID_H + diff --git a/src/misc/wrt_powder_info_util.cpp b/src/misc/wrt_powder_info_util.cpp new file mode 100644 index 0000000..de7bab3 --- /dev/null +++ b/src/misc/wrt_powder_info_util.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file wrt_powder_info_util.h + * @author Justyna Mejzner (j.kwiatkowsk@samsung.com) + * @version 1.0 + */ + +#include "wrt_powder_info_util.h" +#include <dpl/singleton_impl.h> +IMPLEMENT_SINGLETON(PowderInfoUtil) + +PowderInfoUtil::PowderInfoUtil() +{ + m_categories[DPL::FromUTF8String("nu")] = "Nudity"; + m_categories[DPL::FromUTF8String("se")] = "Sex"; + m_categories[DPL::FromUTF8String("vi")] = "Violence"; + m_categories[DPL::FromUTF8String("la")] = "Potentially offensive language"; + m_categories[DPL::FromUTF8String("dr")] = "Drug use"; + m_categories[DPL::FromUTF8String("ga")] = "Gambling"; + m_categories[DPL::FromUTF8String("ha")] = "Hate or harmful activities"; + m_categories[DPL::FromUTF8String("ug")] = "Use of user-generated content"; + + m_contexts[DPL::FromUTF8String("xa")] = "This material appears in" + " an artistic conteaxt"; + m_contexts[DPL::FromUTF8String("xb")] = "This material appears in" + " an educational context"; + m_contexts[DPL::FromUTF8String("xc")] = "This material appears in" + " a medical context"; + m_contexts[DPL::FromUTF8String("xd")] = "This material appears in" + " a sports context"; + m_contexts[DPL::FromUTF8String("xe")] = "This material appears in" + " a violent context"; +} + +std::string PowderInfoUtil::getCategoryLabel(const DPL::String &category) const +{ + CategoryMap::const_iterator categoryIterator = m_categories.find(category); + if (categoryIterator == m_categories.end()) { + ThrowMsg(PowderException::IncorrectTypeError, + "Wrong type of category."); + } + return categoryIterator->second; +} + +std::string PowderInfoUtil::getContextLabel(const DPL::String &context) const +{ + ContextMap::const_iterator contextIterator = m_contexts.find(context); + if (contextIterator == m_contexts.end()) { + ThrowMsg(PowderException::IncorrectTypeError, "Wrong type of context."); + } + return contextIterator->second; +} + diff --git a/src/misc/wrt_powder_info_util.h b/src/misc/wrt_powder_info_util.h new file mode 100644 index 0000000..cf5da70 --- /dev/null +++ b/src/misc/wrt_powder_info_util.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file wrt_powder_info_util.h + * @author Justyna Mejzner (j.kwiatkowsk@samsung.com) + * @version 1.0 + */ + +#ifndef _WRT_SRC_INSTALLERCORE_POWDERINFOUTIL_H_ +#define _WRT_SRC_INSTALLERCORE_POWDERINFOUTIL_H_ + +#include <map> + +#include <dpl/string.h> +#include <dpl/singleton.h> + +class PowderInfoUtil +{ + public: + class PowderException + { + public: + DECLARE_EXCEPTION_TYPE(DPL::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, IncorrectTypeError) + }; + + std::string getCategoryLabel(const DPL::String &category) const; + std::string getContextLabel(const DPL::String &context) const; + + private: + PowderInfoUtil(); + friend class DPL::Singleton<PowderInfoUtil>; + + typedef std::map<DPL::String, std::string> CategoryMap; + typedef std::map<DPL::String, std::string> ContextMap; + CategoryMap m_categories; + ContextMap m_contexts; +}; + +typedef DPL::Singleton<PowderInfoUtil> PowderInfoUtilSingleton; + +#endif /* _WRT_SRC_INSTALLERCORE_POWDERINFOUTIL_H_ */ + diff --git a/src/pkg-manager/CMakeLists.txt b/src/pkg-manager/CMakeLists.txt new file mode 100755 index 0000000..ea06b72 --- /dev/null +++ b/src/pkg-manager/CMakeLists.txt @@ -0,0 +1,67 @@ +# +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# + +SET(BACKLIB_SRCS + backendlib.cpp +) + +PKG_CHECK_MODULES(WRT_BACKLIB_PKGS + dpl-efl + dpl-wrt-dao-ro + dpl-wrt-dao-rw + dpl-utils-efl + pkgmgr-installer + pkgmgr-types + dlog + REQUIRED) + +INCLUDE_DIRECTORIES( + ${WRT_BACKLIB_PKGS_INCLUDE_DIRS} +) + +ADD_LIBRARY(${TARGET_BACKEND_LIB} SHARED + ${BACKLIB_SRCS} +) + +TARGET_LINK_LIBRARIES(${TARGET_BACKEND_LIB} + ${WRT_BACKLIB_PKGS_LIBRARIES} +) + +SET_TARGET_PROPERTIES(${TARGET_BACKEND_LIB} PROPERTIES + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both -Wl" +) + +INSTALL(TARGETS ${TARGET_BACKEND_LIB} + DESTINATION etc/package-manager/backendlib + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +) + +#SYMLINK +set(SYMLINK_USE OFF) +set(SYMLINK_DEST "${CMAKE_INSTALL_PREFIX}/etc/package-manager") + +IF(SYMLINK_USE) + ADD_CUSTOM_COMMAND(OUTPUT ${SYMLINK_DEST}/backend/wgt + COMMAND mkdir + ARGS -p ${SYMLINK_DEST}/backend + COMMAND ln + ARGS -sf ${CMAKE_INSTALL_PREFIX}/bin/${BACKEND} ${SYMLINK_DEST}/backend/wgt + DEPENDS ${BACKEND} + ) + ADD_CUSTOM_TARGET(test_symlinks ALL + DEPENDS ${SYMLINK_DEST}/backend/wgt + ) +ENDIF(SYMLINK_USE) diff --git a/src/pkg-manager/DESCRIPTION b/src/pkg-manager/DESCRIPTION new file mode 100644 index 0000000..a9d3696 --- /dev/null +++ b/src/pkg-manager/DESCRIPTION @@ -0,0 +1 @@ +Executables for interfacing with the package manager diff --git a/src/pkg-manager/backendlib.cpp b/src/pkg-manager/backendlib.cpp new file mode 100755 index 0000000..85b2f5d --- /dev/null +++ b/src/pkg-manager/backendlib.cpp @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * + * + * @file backendlib.cpp + * @author Soyoung Kim (sy037.kim@samsung.com) + * @version 0.1 + * @brief This is implementation file for providing widget information + * to package manager + */ +#include "package-manager-plugin.h" +#include <dlog.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <dpl/ace-dao-rw/AceDAO.h> +#include <vcore/VCore.h> +#include <dpl/wrt-dao-ro/WrtDatabase.h> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <dpl/wrt-dao-ro/feature_dao_read_only.h> +#include <dpl/wrt-dao-ro/widget_config.h> +#include <string> +#include <dpl/db/sql_connection.h> +#include <dpl/log/log.h> +#include <dpl/foreach.h> +#include <dpl/ace-dao-ro/wrt_db_types.h> +#include <dpl/utils/folder_size.h> + +using namespace WrtDB; + +#undef TRUE +#undef FALSE +#define TRUE 0 +#define FALSE -1 +#define GET_DIRECTORY_SIZE_KB(x) (x)/1024 + +#ifdef __cplusplus +extern "C" +{ +#endif + +class DatabaseConnection +{ + public: + void AttachDatabase() + { + WrtDB::WrtDatabase::attachToThread(); + } + + void DetachDatabase() + { + WrtDB::WrtDatabase::detachFromThread(); + } +}; + +static DPL::ScopedPtr<DatabaseConnection> g_databaseConnection; + +static void pkg_native_plugin_on_unload(); +static int pkg_plugin_app_is_installed(const char *pkg_name); +static int pkg_plugin_get_installed_apps_list(const char *category, + const char *option, package_manager_pkg_info_t **list, int *count); +static int pkg_plugin_get_app_detail_info(const char *pkg_name, + package_manager_pkg_detail_info_t *pkg_detail_info); +static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path, + package_manager_pkg_detail_info_t *pkg_detail_info); + +static int is_connected() +{ + if (NULL == g_databaseConnection) { + Try { + g_databaseConnection.Reset(new DatabaseConnection()); + g_databaseConnection->AttachDatabase(); + } + Catch (DPL::DB::SqlConnection::Exception::Base) { + LogDebug("Fail to connect DB"); + return FALSE; + } + } + + return TRUE; +} + +static void pkg_native_plugin_on_unload() +{ + LogDebug("pkg_native_plugin_unload() is called"); +} + +static int pkg_plugin_app_is_installed(const char *pkg_name) +{ + LogDebug("pkg_plugin_app_is_installed() is called"); + + if (FALSE == is_connected()) { + LogError("Fail DB Connect"); + return FALSE; + } + + Try { + if (WidgetDAOReadOnly::isWidgetInstalled( + DPL::FromUTF8String(pkg_name))) { + return TRUE; + } + } Catch(DPL::DB::SqlConnection::Exception::Base) { + LogDebug("Databas Error"); + return FALSE; + } + + LogDebug("Widget Not Found"); + return FALSE; +} + +static int pkg_plugin_get_installed_apps_list(const char * /*category*/, + const char * /*option*/, package_manager_pkg_info_t **list, int *count) +{ + LogDebug("pkg_plugin_get_installed_apps_list() is called"); + + package_manager_pkg_info_t *pkg_list = NULL; + package_manager_pkg_info_t *pkg_last = NULL; + + Try { + if (FALSE == is_connected()) { + LogError("Fail DB Connect"); + return FALSE; + } + + WidgetHandleList hndlList = WidgetDAO::getHandleList(); + *count = 0; + + FOREACH(iterator, hndlList) { + package_manager_pkg_info_t *pkg_info = + static_cast<package_manager_pkg_info_t*> + (malloc(sizeof(package_manager_pkg_info_t))); + if (NULL == pkg_info) { + LogError("Error in malloc"); + return FALSE; + } + + if (NULL == pkg_list) { + pkg_list = pkg_info; + pkg_last = pkg_info; + } else { + pkg_last->next = pkg_info; + } + + WidgetDAO widget(*iterator); + DPL::Optional<DPL::String> pkgname = widget.getPkgname(); + strncpy(pkg_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX); + if(!pkgname.IsNull()) { + snprintf(pkg_info->pkg_name, PKG_NAME_STRING_LEN_MAX, "%s", + DPL::ToUTF8String(*pkgname).c_str()); + } + + DPL::Optional<DPL::String> version = widget.getVersion(); + if (!version.IsNull()) { + strncpy(pkg_info->version, + DPL::ToUTF8String(*version).c_str(), + PKG_VERSION_STRING_LEN_MAX); + } + + (*count)++; + pkg_last = pkg_info; + } + *list = pkg_list; + } + Catch (WidgetDAO::Exception::DatabaseError) { + LogError("Database Error"); + return FALSE; + } + return TRUE; +} + +static int pkg_plugin_get_app_detail_info(const char *pkg_name, + package_manager_pkg_detail_info_t *pkg_detail_info) +{ + LogDebug("pkg_plugin_get_app_detail_info() is called"); + + Try { + if (FALSE == is_connected()) { + LogError("Fail DB Connect"); + return FALSE; + } + + int handle = WidgetDAOReadOnly::getHandle( + DPL::FromUTF8String(pkg_name)); + WidgetDAO widget(handle); + + DPL::Optional<DPL::String> version = widget.getVersion(); + DPL::Optional<DPL::String> id = widget.getGUID(); + DPL::Optional<DPL::String> locale = widget.getDefaultlocale(); + + if (!version.IsNull()) { + strncpy(pkg_detail_info->version, + DPL::ToUTF8String(*version).c_str(), + PKG_VERSION_STRING_LEN_MAX); + } + snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%d", + handle); + WidgetLocalizedInfo localizedInfo; + + if (locale.IsNull()) { + LogError("is NULL"); + DPL::String languageTag(L""); + localizedInfo = widget.getLocalizedInfo(languageTag); + } else { + localizedInfo = widget.getLocalizedInfo(*locale); + } + DPL::Optional<DPL::String> desc(localizedInfo.description); + + if (!desc.IsNull()) { + strncpy(pkg_detail_info->pkg_description, + DPL::ToUTF8String(*desc).c_str(), + PKG_VALUE_STRING_LEN_MAX); + } + strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX); + strncpy(pkg_detail_info->pkg_name, pkg_name, PKG_NAME_STRING_LEN_MAX); + + /* set installed time */ + pkg_detail_info->installed_time = widget.getInstallTime(); + + /* set Widget size */ + DPL::String pkgName = DPL::FromUTF8String(pkg_name); + std::string installPath = WidgetConfig::GetWidgetBasePath(pkgName); + std::string persistentPath = + WidgetConfig::GetWidgetPersistentStoragePath(pkgName); + std::string tempPath = + WidgetConfig::GetWidgetTemporaryStoragePath(pkgName); + installPath += "/"; + tempPath += "/"; + persistentPath += "/"; + + size_t installedSize = Utils::getFolderSize(installPath); + size_t persistentSize = Utils::getFolderSize(persistentPath); + size_t appSize = installedSize - persistentSize; + size_t dataSize = persistentSize + Utils::getFolderSize(tempPath); + + pkg_detail_info->installed_size = GET_DIRECTORY_SIZE_KB(installedSize); + pkg_detail_info->app_size = GET_DIRECTORY_SIZE_KB(appSize); + pkg_detail_info->data_size = GET_DIRECTORY_SIZE_KB(dataSize); + } + Catch (WidgetDAO::Exception::DatabaseError) { + LogError("Database Error"); + return FALSE; + } + return TRUE; +} + +static int pkg_plugin_get_app_detail_info_from_package( + const char * /*pkg_path*/, + package_manager_pkg_detail_info_t * /*pkg_detail_info*/) +{ + LogDebug("pkg_plugin_get_app_detail_info_from_package() is called"); + + return TRUE; +} + +__attribute__ ((visibility("default"))) +int pkg_plugin_on_load(pkg_plugin_set *set) +{ + DPL::Log::LogSystemSingleton::Instance().SetTag("WGT-BACKLIB"); + if (NULL == set) { + return FALSE; + } + memset(set, 0x00, sizeof(pkg_plugin_set)); + + set->plugin_on_unload = pkg_native_plugin_on_unload; + set->pkg_is_installed = pkg_plugin_app_is_installed; + set->get_installed_pkg_list = pkg_plugin_get_installed_apps_list; + set->get_pkg_detail_info = pkg_plugin_get_app_detail_info; + set->get_pkg_detail_info_from_package = + pkg_plugin_get_app_detail_info_from_package; + + return TRUE; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/security/ace_settings_logic.cpp b/src/security/ace_settings_logic.cpp new file mode 100644 index 0000000..d980f02 --- /dev/null +++ b/src/security/ace_settings_logic.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file ace_settings_logic.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This is an implementation of server of ACE user preferences + */ +#include <ace_settings_logic.h> +#include <ace_settings_server_factory.h> +#include <dpl/foreach.h> +#include <dpl/assert.h> +#include <dpl/log/log.h> +//#include <widget_controller.h> +#include <dpl/localization/w3c_file_localization.h> +#include <dpl/ace/PolicyEnforcementPoint.h> +#include <dpl/ace/PolicyEvaluator.h> +#include <dpl/ace/Preference.h> +#include <dpl/wrt-dao-rw/feature_dao.h> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <vector> +#include <map> + +#include <dpl/ace-dao-rw/AceDAO.h> +#include <dpl/ace/SettingsLogic.h> +#include <dpl/wrt-dao-rw/global_dao.h> + +using namespace WrtDB; + +namespace // anonymous +{ +struct SubjectResource +{ + WidgetHandle subject; // app_id + std::string resource; + + SubjectResource(WidgetHandle subjectArg, + const std::string& resourceArg) : + subject(subjectArg), + resource(resourceArg) + { + } + + bool operator < (const SubjectResource& subjectResource) const + { + if (subject != subjectResource.subject) { + return subject < subjectResource.subject; + } else { + return resource < subjectResource.resource; + } + } +}; + +typedef std::map<SubjectResource, Preference> WidgetResourcePreferenceMap; +} // namespace anonymous + +AceSettingsLogic::AceSettingsLogic( + PolicyEnforcementPoint *policyEnforcementPoint) : + m_policyEnforcementPoint(policyEnforcementPoint) +{ + // Acquire ACE settings server from factory + m_server = AceSettingsServerFactory::Create(this); +} + +AceSettings::WidgetsPreferences AceSettingsLogic::getWidgetsPreferences() const +{ + AceSettings::WidgetsPreferences widgetsPreferences; + WidgetHandleList widgetHandleList = WidgetDAOReadOnly::getHandleList(); + + DPL::ScopedPtr<WidgetResourcePreferenceMap> preferenceMap; + + PermissionList permissionTriple; + SettingsLogic::getWidgetDevCapSettings(&permissionTriple); + + preferenceMap.Reset(new WidgetResourcePreferenceMap()); + + FOREACH(permission, permissionTriple) + { + LogInfo("In db: " << permission->appId << + " " << permission->devCap); + SubjectResource sb(permission->appId, + permission->devCap); + preferenceMap->insert(std::make_pair(sb, permission->access)); + } + + LogInfo("Sending Widget Resources"); + + FOREACH(handle, widgetHandleList) + { + AceSettings::SubjectResourcePreferences subjectResourcePreferences; + WidgetDAOReadOnly widget(*handle); + + //This has to be redesigned how to gather localized name of widget +// auto lang = widget.getDefaultlocale(); +// if (!lang) lang = DPL::FromASCIIString("en"); +// WidgetLocalizedInfo info = +// widget.getLocalizedInfo(*lang); +// +// DPL::Optional<DPL::String> optionalName = info.name; +// +// if (!!optionalName) { +// LogDebug("optional name: " << (*optionalName)); +// subjectResourcePreferences.subject = +// DPL::ToUTF8String(*optionalName); +// } else { +// subjectResourcePreferences.subject = ""; +// } + + WidgetFeatureSet featureSet = widget.getFeaturesList(); + SubjectResource subjectResource(*handle, ""); + + DeviceCapabilitySet deviceCaps; + + FOREACH(feature, featureSet) + { + DeviceCapabilitySet thisFeatureDeviceCaps = + GlobalDAO::GetDeviceCapability(feature->name); + deviceCaps.insert(thisFeatureDeviceCaps.begin(), + thisFeatureDeviceCaps.end()); + } + + FOREACH(deviceCap, deviceCaps) + { + AceSettings::ResourcePreference resourcePreferences; + resourcePreferences.resource = DPL::ToUTF8String(*deviceCap); + + subjectResource.resource = resourcePreferences.resource; + LogInfo("Looking for: " << subjectResource.subject << + " " << subjectResource.resource); + + if (preferenceMap) { + WidgetResourcePreferenceMap::const_iterator preference = + preferenceMap->find(subjectResource); + + if (preference != preferenceMap->end()) { + LogInfo("Found not default preference!!"); + resourcePreferences.preference = preference->second; + } else { + resourcePreferences.preference = Preference::PREFERENCE_DEFAULT; + } + } else { + resourcePreferences.preference = Preference::PREFERENCE_DEFAULT; + } + + LogInfo("Pushing back resource preference"); + + subjectResourcePreferences.resourcesPreference. + push_back(resourcePreferences); + } + + widgetsPreferences.subjectsResourcePreferences.push_back( + subjectResourcePreferences); + } + + return widgetsPreferences; +} + +AceSettings::ResourcesPreferences AceSettingsLogic::getResourcesPreferences() +const +{ + AceSettings::ResourcesPreferences resourcesPreferences; + PreferenceMap preferenceMap; + + SettingsLogic::getDevCapSettings(&preferenceMap); + + FeatureHandleList featureList = FeatureDAOReadOnly::GetHandleList(); + + FOREACH(featureName, featureList) + { + FeatureDAOReadOnly featureDao(*featureName); + + AceSettings::ResourcePreference resourcePreference; + resourcePreference.resource = featureDao.GetName(); + + PreferenceMap::const_iterator preference = + preferenceMap.find(resourcePreference.resource); + + if (preference != preferenceMap.end()) { + resourcePreference.preference = preference->second; + } else { + resourcePreference.preference = Preference::PREFERENCE_DEFAULT; + } + + resourcesPreferences.resourcesPreference.push_back(resourcePreference); + } + + return resourcesPreferences; +} + +void AceSettingsLogic::setWidgetPreference(const std::string &resource, + WidgetHandle handler, + const Preference &preference) +{ + SettingsLogic::setWidgetDevCapSetting(resource, handler, preference); +} + +void AceSettingsLogic::setResourcePreference(const std::string &resource, + const Preference &preference) +{ + SettingsLogic::setDevCapSetting(resource, preference); +} + +bool AceSettingsLogic::getWidgetsSecure() const +{ + return GlobalDAO::GetSecureByDefault(); +} + +void AceSettingsLogic::setWidgetsSecure(bool widgetSecure) +{ + GlobalDAO::SetSecureByDefault(widgetSecure); +} + +void AceSettingsLogic::resetWidgetsPreferences() +{ + AceDB::AceDAO::clearWidgetDevCapSettings(); +} + +void AceSettingsLogic::resetResourcesPreferences() +{ + AceDB::AceDAO::clearDevCapSettings(); +} diff --git a/src/security/ace_settings_logic.h b/src/security/ace_settings_logic.h new file mode 100644 index 0000000..fd91399 --- /dev/null +++ b/src/security/ace_settings_logic.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file ace_settings_logic.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This is a header of server of ACE user preferences + */ +#ifndef WRT_SRC_ACCESS_CONTROL_IPC_SETTINGS_ACE_SETTINGS_LOGIC_H_ +#define WRT_SRC_ACCESS_CONTROL_IPC_SETTINGS_ACE_SETTINGS_LOGIC_H_ + +#include <dpl/shared_ptr.h> +#include <i_ace_settings_server.h> +#include <i_ace_settings_client.h> +#include <string> + +#include <dpl/ace-dao-ro/wrt_db_types.h> + +class PolicyEnforcementPoint; + +class AceSettingsLogic +{ + public: + void setWidgetPreference(const std::string &resource, + WidgetHandle handler, + const AceDB::PreferenceTypes &preference); + + void setResourcePreference(const std::string &resource, + const AceDB::PreferenceTypes &preference); + + AceSettings::WidgetsPreferences getWidgetsPreferences() const; + + AceSettings::ResourcesPreferences getResourcesPreferences() const; + + bool getWidgetsSecure() const; + + void setWidgetsSecure(bool widgetSecure); + + void resetWidgetsPreferences(); + void resetResourcesPreferences(); + + private: + AceSettingsLogic(PolicyEnforcementPoint *policyEnforcementPoint); + + friend class SecurityLogic; + friend class PolicyEnforcementPoint; + + // PEP + PolicyEnforcementPoint *m_policyEnforcementPoint; + + // Ace settings server (may be null) + DPL::SharedPtr<IAceSettingsServer> m_server; +}; + +#endif // WRT_SRC_ACCESS_CONTROL_IPC_SETTINGS_ACE_SETTINGS_LOGIC_H_ diff --git a/src/security/attribute_facade.cpp b/src/security/attribute_facade.cpp new file mode 100644 index 0000000..72db14b --- /dev/null +++ b/src/security/attribute_facade.cpp @@ -0,0 +1,871 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * + * This file contains classes that implement WRT_INTERFACE.h interfaces, + * so that ACE could access WRT specific and other information during + * the decision making. + * + * @file attribute_.cpp + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Ming Jin(ming79.jin@samsung.com) + * @version 1.0 + * @brief Implementation file for attributes obtaining. + */ + +#include <dpl/exception.h> +#include <sstream> +#include <algorithm> +#include <list> +#include <string> +#include <sstream> +#include <stdexcept> +#include <map> +#include <cstdlib> +#include <dpl/wrt-dao-rw/widget_dao.h> +#include <dpl/wrt-dao-rw/feature_dao.h> +#include <dpl/ace/WRT_INTERFACE.h> +#include <map> +#include <dpl/log/log.h> +#include <attribute_facade.h> +#include <dpl/ace/Request.h> +#include <simple_roaming_agent.h> + +using namespace WrtDB; + +namespace // anonymous +{ +typedef std::list<std::string> AttributeHandlerResponse; + +typedef AttributeHandlerResponse (*AttributeHandler)( + const WidgetExecutionPhase &phase, + const WidgetHandle &widgetHandle); +typedef AttributeHandlerResponse (*ResourceAttributeHandler)( + const WidgetExecutionPhase &phase, + const WidgetHandle &widgetHandle, + const Request &request); + +AttributeHandlerResponse AttributeClassHandler(const WidgetExecutionPhase & /*phase*/, + const WidgetHandle & /*widgetHandle*/) +{ + AttributeHandlerResponse response; + response.push_back("widget"); + return response; +} + +AttributeHandlerResponse AttributeInstallUriHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + std::string value = dao.getShareHref(); + + if (!value.empty()) { + response.push_back(value); + } + + return response; +} + +AttributeHandlerResponse AttributeVersionHandler(const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + DPL::Optional<DPL::String> value = dao.getVersion(); + + if (!!value) { + response.push_back(DPL::ToUTF8String(*value)); + } + + return response; +} + +AttributeHandlerResponse AttributeDistributorKeyCnHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyCommonNameList(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ENDENTITY); + + return response; +} + +AttributeHandlerResponse AttributeDistributorKeyFingerprintHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyFingerprints(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ENDENTITY); + + return response; +} + +AttributeHandlerResponse AttributeDistributorKeyRootCnHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyCommonNameList(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ROOT); + + return response; +} + +AttributeHandlerResponse AttributeDistributorKeyRootFingerprintHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyFingerprints(WidgetCertificateData::DISTRIBUTOR, + WidgetCertificateData::ROOT); + + return response; +} + +AttributeHandlerResponse AttributeAuthorKeyCnHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyCommonNameList(WidgetCertificateData::AUTHOR, + WidgetCertificateData::ENDENTITY); + + return response; +} + +AttributeHandlerResponse AttributeAuthorKeyFingerprintHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyFingerprints(WidgetCertificateData::AUTHOR, + WidgetCertificateData::ENDENTITY); + + return response; +} + +AttributeHandlerResponse AttributeAuthorKeyRootCnHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyCommonNameList(WidgetCertificateData::AUTHOR, + WidgetCertificateData::ROOT); + + return response; +} + +AttributeHandlerResponse AttributeAuthorKeyRootFingerprintHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + response = dao.getKeyFingerprints(WidgetCertificateData::AUTHOR, + WidgetCertificateData::ROOT); + + return response; +} + +AttributeHandlerResponse AttributeNetworkAccessUriHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle & /*widgetHandle*/) +{ + AttributeHandlerResponse response; + return response; +} + +AttributeHandlerResponse AttributeIdHandler(const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + WidgetGUID wGUID = dao.getGUID(); + + if (!!wGUID) { + response.push_back(DPL::ToUTF8String(*wGUID)); + } + return response; +} + +//AttributeHandlerResponse AttributeNameHandler(const WidgetExecutionPhase & /*phase*/, +// const WidgetHandle &widgetHandle) +//{ +// AttributeHandlerResponse response; +// +// WidgetLocalizedInfo info = +// W3CFileLocalization::getLocalizedInfo(widgetHandle); +// +// DPL::Optional<DPL::String> val = info.name; +// std::string value = !!val ? DPL::ToUTF8String(*val) : ""; +// +// response.push_back(value); +// return response; +//} +// +//AttributeHandlerResponse AttributeWidgetAttrNameHandler( +// const WidgetExecutionPhase & /*phase*/, +// const WidgetHandle &widgetHandle) +//{ +// AttributeHandlerResponse response; +// +// WidgetLocalizedInfo info = +// W3CFileLocalization::getLocalizedInfo(widgetHandle); +// +// DPL::Optional<DPL::String> value = info.name; +// +// if (!!value) { +// response.push_back(DPL::ToUTF8String(*value)); +// } +// +// return response; +//} + +AttributeHandlerResponse AttributeAuthorNameHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle) +{ + AttributeHandlerResponse response; + WidgetDAOReadOnly dao(widgetHandle); + + DPL::Optional<DPL::String> value = dao.getAuthorName(); + + if (!!value) { + response.push_back(DPL::ToUTF8String(*value)); + } + + return response; +} + +AttributeHandlerResponse AttributeRoamingHandler( + const WidgetExecutionPhase &phase, + const WidgetHandle & /*widgetHandle*/) +{ + AttributeHandlerResponse response; + + if (WidgetExecutionPhase_WidgetInstall == phase) { + // TODO undetermind value + response.push_back(std::string("")); + } else if (SimpleRoamingAgentSingleton::Instance().IsRoamingOn()) { + response.push_back(std::string("true")); + } else { + response.push_back(std::string("false")); + } + + return response; +} + +AttributeHandlerResponse AttributeBearerTypeHandler( + const WidgetExecutionPhase & /*phase*/, + const WidgetHandle & /*widgetHandle*/) +{ + AttributeHandlerResponse response; + + std::string bearerName = "undefined-bearer-name"; + + if (bearerName.empty()) { + LogWarning("Bearer-type is NOT SET or empty"); + } else { + response.push_back(bearerName); + } + + return response; +} + +struct AttributeHandlerContext +{ + std::string name; + WidgetExecutionPhase allowedPhaseMask; + AttributeHandler handler; +}; + +// Private masks +const WidgetExecutionPhase WidgetExecutionPhase_All = + static_cast<WidgetExecutionPhase>( + WidgetExecutionPhase_WidgetInstall | + WidgetExecutionPhase_WidgetInstantiate | + WidgetExecutionPhase_WebkitBind | + WidgetExecutionPhase_Invoke); +const WidgetExecutionPhase WidgetExecutionPhase_NoWidgetInstall = + static_cast<WidgetExecutionPhase>( + WidgetExecutionPhase_WidgetInstantiate | + WidgetExecutionPhase_WebkitBind | + WidgetExecutionPhase_Invoke); + +#define ALL_PHASE(name, handler) \ + { # name, WidgetExecutionPhase_All, handler }, + +#define NO_INSTALL(name, handler) \ + { # name, WidgetExecutionPhase_NoWidgetInstall, handler }, + +AttributeHandlerContext HANDLED_ATTRIBUTES_LIST[] = { + ALL_PHASE(Class, &AttributeClassHandler) + ALL_PHASE(install-uri, &AttributeInstallUriHandler) + ALL_PHASE(version, &AttributeVersionHandler) + ALL_PHASE(distributor-key-cn, &AttributeDistributorKeyCnHandler) + ALL_PHASE(distributor-key-fingerprint, + &AttributeDistributorKeyFingerprintHandler) + ALL_PHASE(distributor-key-root-cn, + &AttributeDistributorKeyRootCnHandler) + ALL_PHASE(distributor-key-root-fingerprint, + &AttributeDistributorKeyRootFingerprintHandler) + ALL_PHASE(author-key-cn, &AttributeAuthorKeyCnHandler) + ALL_PHASE(author-key-fingerprint, &AttributeAuthorKeyFingerprintHandler) + ALL_PHASE(author-key-root-cn, &AttributeAuthorKeyRootCnHandler) + ALL_PHASE(author-key-root-fingerprint, + &AttributeAuthorKeyRootFingerprintHandler) + ALL_PHASE(network-access-uri, &AttributeNetworkAccessUriHandler) + ALL_PHASE(id, &AttributeIdHandler) +// ALL_PHASE(name, &AttributeNameHandler) +// ALL_PHASE(widget-attr:name, &AttributeWidgetAttrNameHandler) + ALL_PHASE(author-name, &AttributeAuthorNameHandler) + /* Enviroment attributes*/ + NO_INSTALL(roaming, &AttributeRoamingHandler) + NO_INSTALL(bearer-type, &AttributeBearerTypeHandler) +}; + +#undef ALL_PHASE +#undef NO_INSTALL + +const size_t HANDLED_ATTRIBUTES_LIST_COUNT = + sizeof(HANDLED_ATTRIBUTES_LIST) / sizeof(HANDLED_ATTRIBUTES_LIST[0]); + +template<class T> +class lambdaCollectionPusher +{ + public: + std::list<T>& m_collection; + lambdaCollectionPusher(std::list<T>& collection) : m_collection(collection) + { + } + void operator()(const T& element) const + { + m_collection.push_back(element); + } +}; + +class lambdaWidgetPrefixEquality : + public std::binary_function<WidgetFeature, std::string, bool> +{ + public: + bool operator()(const WidgetFeature& wFeature, + const std::string& prefix) const + { + return wFeature.name.find(DPL::FromUTF8String(prefix)) != + DPL::String::npos; + } +}; + +class lambdaWidgetNameEquality : + public std::binary_function<WidgetFeature, std::string, bool> +{ + public: + bool operator()(const WidgetFeature& wFeature, + const std::string& prefix) const + { + return wFeature.name == DPL::FromUTF8String(prefix); + } +}; + +FeatureHandleList getFeatureHandleList(const WidgetHandle& widgetHandle, + const std::string& resourceId) +{ + FeatureHandleList featureHandleList; + WidgetDAOReadOnly widgetDAO(widgetHandle); + WidgetFeatureSet wFeatureSet = widgetDAO.getFeaturesList(); + WidgetFeatureSet::iterator foundFeatures = + std::find_if(wFeatureSet.begin(), + wFeatureSet.end(), + std::bind2nd(lambdaWidgetPrefixEquality(), resourceId)); + + if (foundFeatures != wFeatureSet.end()) { + FeatureDAOReadOnly featureDAO(resourceId); + featureHandleList.push_back(featureDAO.GetFeatureHandle()); + } + return featureHandleList; +} + +AttributeHandlerResponse AttributeDeviceCapHandler(const WidgetExecutionPhase & /*phase*/, + const WidgetHandle & /*widgetHandle*/, + const Request &request) +{ + AttributeHandlerResponse response; + + Request::DeviceCapabilitySet capSet = request.getDeviceCapabilitySet(); + + std::for_each( + capSet.begin(), + capSet.end(), + lambdaCollectionPusher<std::string>(response)); + + return response; + + // We should return list of device-caps required by resourceId. + // AttributeHandlerResponse response; + // + // FeatureHandleList fHandleList = + // getFeatureHandleList(widgetHandle, resourceId); + // if( !fHandleList.empty() ) + // { + // FeatureDAO feature( resourceId ); + // std::set<std::string> deviceCapLast = + // feature.GetDeviceCapabilities(); + // std::for_each( + // deviceCapList.begin(), + // deviceCapList.end(), + // lambdaCollectionPusher<DeviceCapList::value_type>( + // response) ); + // } + // return response; +} + +class lambdaFeatureEquality : + public std::binary_function<FeatureHandle, int, bool> +{ + public: + bool operator()(const FeatureHandle& wFeature, + const int& resurceId) const + { + return wFeature == resurceId; + } +}; + +class lambdaPushFeatureName : + public std::binary_function<WidgetFeature, AttributeHandlerResponse, void> +{ + void operator()(const WidgetFeature& wFeature, + AttributeHandlerResponse& response) const + { + response.push_back(DPL::ToUTF8String(wFeature.name)); + } +}; + +AttributeHandlerResponse AttributeApiFeatureHandler( + const WidgetExecutionPhase & /* phase */, + const WidgetHandle & /* widgetHandle */, + const Request & /* request */) +{ + LogDebug("WAC 2.0 does not support api-feature and resource-id in policy."); + AttributeHandlerResponse response; + return response; + // Wrt shouldn't ask about resource which is not listed in + // (widget) config.xml file + // + // AttributeHandlerResponse response; + // WidgetDAOReadOnly widgetDAO(widgetHandle); + // WidgetFeatureSet wFeatureSet = widgetDAO.GetFeaturesList(); + // std::string featureName = resourceId; + // WidgetFeatureSet::iterator foundFeatures = + // std::find_if(wFeatureSet.begin(), + // wFeatureSet.end(), + // std::bind2nd(lambdaWidgetPrefixEquality(), + // featureName)); + // + // while( foundFeatures != wFeatureSet.end() ) + // { + // response.push_back( foundFeatures->name ); + // LogDebug("Found feature: " << foundFeatures->name ); + // foundFeatures++; + // } + // + // return response; +} + +typedef std::string (FeatureDAOReadOnly::*FNMETHOD)() const; + +AttributeHandlerResponse GetFeatureAttributeGroup(const WidgetExecutionPhase & /*phase*/, + const WidgetHandle &widgetHandle, + const std::string& resourceId, + FNMETHOD function) +{ + AttributeHandlerResponse response; + FeatureHandleList fHandleList = + getFeatureHandleList(widgetHandle, resourceId); + if (!fHandleList.empty()) { + FeatureDAOReadOnly featureDAO(fHandleList.front()); + std::string attribute = (featureDAO.*function)(); + response.push_back(attribute); + } + return response; +} + +AttributeHandlerResponse AttributeFeatureInstallUriHandler( + const WidgetExecutionPhase & /* phase */, + const WidgetHandle & /* widgetHandle */, + const Request & /* request */) +{ + LogDebug("WAC 2.0 does not support feature-install-uri is policy!"); + AttributeHandlerResponse response; + return response; +} + +AttributeHandlerResponse AttributeFeatureFeatureKeyCnHandler( + const WidgetExecutionPhase & /* phase */, + const WidgetHandle & /* widgetHandle */, + const Request & /* request */) +{ + LogDebug("WAC 2.0 does not support feature-key-cn is policy!"); + AttributeHandlerResponse response; + return response; +} + +AttributeHandlerResponse AttributeFeatureKeyRootCnHandler( + const WidgetExecutionPhase & /* phase */, + const WidgetHandle & /* widgetHandle */, + const Request & /* request */) +{ + LogDebug("WAC 2.0 does not support feature-key-root-cn is policy!"); + AttributeHandlerResponse response; + return response; +} + +AttributeHandlerResponse AttributeFeatureKeyRootFingerprintHandler( + const WidgetExecutionPhase & /* phase */, + const WidgetHandle & /* widgetHandle */, + const Request & /* request */) +{ + LogDebug("WAC 2.0 does not support" + " feature-key-root-fingerprint is policy!"); + AttributeHandlerResponse response; + return response; +} + +struct ResourceAttributeHandlerContext +{ + std::string name; + WidgetExecutionPhase allowedPhaseMask; + ResourceAttributeHandler handler; +}; + +#define ALL_PHASE(name, handler) \ + { # name, WidgetExecutionPhase_All, handler }, + +ResourceAttributeHandlerContext HANDLED_RESOURCE_ATTRIBUTES_LIST[] = { + ALL_PHASE(device-cap, &AttributeDeviceCapHandler) + ALL_PHASE(api-feature, &AttributeApiFeatureHandler) + // [P.Fatyga] For compatiblity with older policies we tread resource-id + // identically as api-feature + ALL_PHASE(resource-id, &AttributeApiFeatureHandler) + + ALL_PHASE(feature-install-uri, &AttributeFeatureInstallUriHandler) + ALL_PHASE(feature-key-cn, &AttributeFeatureFeatureKeyCnHandler) + ALL_PHASE(feature-key-root-cn, &AttributeFeatureKeyRootCnHandler) + ALL_PHASE(feature-key-root-fingerprint, + &AttributeFeatureKeyRootFingerprintHandler) +}; + +#undef ALL_PHASE + +const size_t HANDLED_RESOURCE_ATTRIBUTES_LIST_COUNT = + sizeof(HANDLED_RESOURCE_ATTRIBUTES_LIST) / + sizeof(HANDLED_RESOURCE_ATTRIBUTES_LIST[0]); +} // namespace anonymous + +/* + * class WebRuntimeImpl + */ +int WebRuntimeImpl::getAttributesValuesLoop(const Request &request, + std::list<ATTRIBUTE>* attributes, + WidgetExecutionPhase executionPhase) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + WidgetHandle widgetHandle = request.getWidgetHandle(); + + FOREACH(itr, *attributes) + { + // Get attribute name + std::string attribute = *itr->first; + + // Search for attribute handler + bool attributeFound = false; + + for (size_t i = 0; i < HANDLED_ATTRIBUTES_LIST_COUNT; ++i) { + if (HANDLED_ATTRIBUTES_LIST[i].name == attribute) { + // Check if execution phase is valid + if ((executionPhase & + HANDLED_ATTRIBUTES_LIST[i].allowedPhaseMask) == 0) { + // Attribute found, but execution state + // forbids to execute handler + LogWarning( + "Request for attribute: '" << + attribute << "' which is supported " << + "but forbidden at widget execution phase: " + << + executionPhase); + } else { + // Execution phase allows handler + AttributeHandlerResponse attributeResponse = + (*HANDLED_ATTRIBUTES_LIST[i].handler)( + executionPhase, + widgetHandle); + std::copy(attributeResponse.begin(), + attributeResponse.end(), + std::back_inserter(*itr->second)); + } + + attributeFound = true; + break; + } + } + + if (!attributeFound) { + LogWarning("Request for attribute: '" << + attribute << "' which is not supported"); + } + } + + return 0; + } + UNHANDLED_EXCEPTION_HANDLER_END +} + +int WebRuntimeImpl::getAttributesValues(const Request &request, + std::list<ATTRIBUTE>* attributes) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // Get current execution state + WidgetExecutionPhase executionPhase = + request.getExecutionPhase(); + + return getAttributesValuesLoop(request, attributes, executionPhase); + } + UNHANDLED_EXCEPTION_HANDLER_END +} + +std::string WebRuntimeImpl::getSessionId(const Request & /* request */) +{ + std::string result; + LogError("Not implemented!"); + return result; +} + +WebRuntimeImpl::WebRuntimeImpl() +{ +} + +/* + * class ResourceInformationImpl + */ + +int ResourceInformationImpl::getAttributesValuesLoop(const Request &request, + std::list<ATTRIBUTE>* attributes, + WidgetExecutionPhase executionPhase) +{ + // Currently, we assume widgets have internal representation of integer IDs + WidgetHandle widgetHandle = request.getWidgetHandle(); + //TODO add resource id string analyzys + FOREACH(itr, *attributes) + { + // Get attribute name + std::string attribute = *itr->first; + + // Search for attribute handler + bool attributeFound = false; + + for (size_t i = 0; i < HANDLED_RESOURCE_ATTRIBUTES_LIST_COUNT; ++i) { + if (HANDLED_RESOURCE_ATTRIBUTES_LIST[i].name == attribute) { + // Check if execution phase is valid + if ((executionPhase & + HANDLED_RESOURCE_ATTRIBUTES_LIST[i].allowedPhaseMask) == + 0) { + // Attribute found, but execution state + // forbids to execute handler + LogDebug( + "Request for attribute: '" << + attribute << + "' which is supported but forbidden " << + "at widget execution phase: " << executionPhase); + itr->second = NULL; + } else { + // Execution phase allows handler + AttributeHandlerResponse attributeResponse = + (*HANDLED_RESOURCE_ATTRIBUTES_LIST[i].handler)( + executionPhase, + widgetHandle, + request); + std::copy(attributeResponse.begin(), + attributeResponse.end(), + std::back_inserter(*itr->second)); + + std::ostringstream attributeResponseFull; + + for (AttributeHandlerResponse::const_iterator + it = attributeResponse.begin(); + it != attributeResponse.end(); ++it) { + attributeResponseFull << + (it == attributeResponse.begin() ? "" : ", ") << + *it; + } + + LogDebug("Attribute(" << attribute << ") = " << + attributeResponseFull.str()); + } + + attributeFound = true; + break; + } + } + + if (!attributeFound) { + LogWarning("Request for attribute: '" << attribute << + "' which is not supported"); + } + } + return 0; +} + +int ResourceInformationImpl::getAttributesValues(const Request &request, + std::list<ATTRIBUTE>* attributes) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // Get current execution state + WidgetExecutionPhase executionPhase = + request.getExecutionPhase(); + return getAttributesValuesLoop(request, attributes, executionPhase); + } + UNHANDLED_EXCEPTION_HANDLER_END +} + +ResourceInformationImpl::ResourceInformationImpl() +{ +} + +/* + * class OperationSystemImpl + */ + +int OperationSystemImpl::getAttributesValues(const Request &request, + std::list<ATTRIBUTE>* attributes) +{ + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + //FIXME: + //GetExecution name without widget name + WidgetExecutionPhase executionPhase = + request.getExecutionPhase(); + + FOREACH(itr, *attributes) + { + // Get attribute name + std::string attribute = *itr->first; + + // Search for attribute handler + bool attributeFound = false; + + for (size_t i = 0; i < HANDLED_ATTRIBUTES_LIST_COUNT; ++i) { + if (HANDLED_ATTRIBUTES_LIST[i].name == attribute) { + // Check if execution phase is valid + if ((executionPhase & + HANDLED_ATTRIBUTES_LIST[i].allowedPhaseMask) == 0) { + // Attribute found, but execution state forbids + // to execute handler + LogDebug("Request for attribute: '" << attribute << + "' which is supported but forbidden at " << + "widget execution phase: " << executionPhase); + itr->second = NULL; + } else { + // Execution phase allows handler + AttributeHandlerResponse attributeResponse = + (*HANDLED_ATTRIBUTES_LIST[i].handler)( + executionPhase, + 0); + std::copy(attributeResponse.begin(), + attributeResponse.end(), + std::back_inserter(*itr->second)); + + std::ostringstream attributeResponseFull; + + typedef AttributeHandlerResponse::const_iterator Iter; + FOREACH(it, attributeResponse) + { + attributeResponseFull << + (it == attributeResponse.begin() + ? "" : ", ") << *it; + } + + LogDebug("Attribute(" << attribute << + ") = " << attributeResponseFull.str()); + } + + attributeFound = true; + break; + } + } + + if (!attributeFound) { + LogWarning("Request for attribute: '" << attribute << + "' which is not supported"); + } + } + + return 0; + } + UNHANDLED_EXCEPTION_HANDLER_END +} + +OperationSystemImpl::OperationSystemImpl() +{ +} + +/* + * end of class OperationSystemImpl + */ + +int FunctionParamImpl::getAttributesValues(const Request & /*request*/, + std::list<ATTRIBUTE> *attributes) +{ + FOREACH(iter, *attributes) + { + std::string attributeName = *(iter->first); + + ParamMap::const_iterator i; + std::pair<ParamMap::const_iterator, ParamMap::const_iterator> jj = + paramMap.equal_range(attributeName); + + for (i = jj.first; i != jj.second; ++i) { + iter->second->push_back(i->second); + LogDebug("Attribute: " << attributeName << " Value: " << + i->second); + } + } + return 0; +} + diff --git a/src/security/attribute_facade.h b/src/security/attribute_facade.h new file mode 100644 index 0000000..e3a8cfd --- /dev/null +++ b/src/security/attribute_facade.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file attribute_facade.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file contains the declaration of WebRuntimeImpl, + * ResourceInformationImpl, OperationSystemImpl + */ + +#ifndef ATTRIBUTE_FACADE_H +#define ATTRIBUTE_FACADE_H + +#include <string> +#include <map> +#include <vector> + +#include <dpl/ace/WRT_INTERFACE.h> + +class Request; + +class WebRuntimeImpl : public IWebRuntime +{ + public: + // Return current sessionId + int getAttributesValuesLoop(const Request &request, + std::list<ATTRIBUTE>* attributes, + WidgetExecutionPhase executionPhase); + + int getAttributesValues(const Request &request, + std::list<ATTRIBUTE>* attributes); + virtual std::string getSessionId(const Request &request); + WebRuntimeImpl(); +}; + +class ResourceInformationImpl : public IResourceInformation +{ + public: + int getAttributesValuesLoop(const Request &request, + std::list<ATTRIBUTE>* attributes, + WidgetExecutionPhase executionPhase); + int getAttributesValues(const Request &request, + std::list<ATTRIBUTE>* attributes); + ResourceInformationImpl(); +}; + +class OperationSystemImpl : public IOperationSystem +{ + public: + /** + * gather and set attributes values for specified attribute name + * @param attributes is a list of pairs( + * first: pointer to attribute name + * second: list of values for attribute (std::string) - + * its a list of string (BONDI requirement), but usually there + * will be only one string + */ + int getAttributesValues(const Request &request, + std::list<ATTRIBUTE>* attributes); + OperationSystemImpl(); +}; + +class FunctionParamImpl : public IFunctionParam +{ + public: + virtual int getAttributesValues(const Request & /*request*/, + std::list<ATTRIBUTE> *attributes); + void addAttribute(const std::string &key, + const std::string &value) + { + paramMap.insert(make_pair(key, value)); + } + virtual ~FunctionParamImpl() + { + } + + private: + typedef std::multimap<std::string, std::string> ParamMap; + ParamMap paramMap; +}; + +typedef std::vector <FunctionParamImpl> FunctionParams; + +#endif //ATTRIBUTE_FACADE_H diff --git a/src/security/i_ace_permissions.h b/src/security/i_ace_permissions.h new file mode 100644 index 0000000..3935c9d --- /dev/null +++ b/src/security/i_ace_permissions.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * + * @file i_ace_settings.h + * @author Jaroslaw Osmanski (j.osmanski@samsung.com) + * @version 1.0 + * @brief This is header file for preference settings interface between + * security controller and clients + */ + +#ifndef WRT_SRC_ACCESS_CONTROL_I_ACE_PERMISSSIONS_H_ +#define WRT_SRC_ACCESS_CONTROL_I_ACE_PERMISSSIONS_H_ + +#include <vector> +#include <dpl/ace-dao-ro/PreferenceTypes.h> + +namespace AceSettings { + +struct ResourcePreference +{ + std::string resource; + AceDB::PreferenceTypes preference; + + ResourcePreference() + { + } + + ResourcePreference(const std::string &resourceArg, + const AceDB::PreferenceTypes &preferenceArg) : + resource(resourceArg), + preference(preferenceArg) + { + } +}; + +struct SubjectResourcePreferences +{ + std::string subject; + std::vector<ResourcePreference> resourcesPreference; + + SubjectResourcePreferences() + { + } + + SubjectResourcePreferences( + const std::string &subjectArg, + const std::vector<ResourcePreference> &resourcesPreferenceArg) : + subject(subjectArg), + resourcesPreference(resourcesPreferenceArg) + { + } +}; + +struct WidgetsPreferences +{ + std::vector<SubjectResourcePreferences> subjectsResourcePreferences; +}; + +struct ResourcesPreferences +{ + std::vector<ResourcePreference> resourcesPreference; +}; + +} // end of namespace AceSettings + +#endif /* WRT_SRC_ACCESS_CONTROL_I_ACE_PERMISSSIONS_H_ */ diff --git a/src/security/i_ace_settings_client.h b/src/security/i_ace_settings_client.h new file mode 100644 index 0000000..d9f6b92 --- /dev/null +++ b/src/security/i_ace_settings_client.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file i_ace_settings_client.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This is a header file for interface of ACE settings client + */ +#ifndef WRT_SRC_UI_SHARED_GADGET_IACESETTINGSCLIENT_H_ +#define WRT_SRC_UI_SHARED_GADGET_IACESETTINGSCLIENT_H_ + +#include <dpl/fast_delegate.h> +#include <dpl/ace-dao-ro/PreferenceTypes.h> +#include <string> +#include <vector> +#include <i_ace_permissions.h> + +namespace AceSettings { + +class IClient +{ + public: + typedef DPL::FastDelegate<void (const WidgetsPreferences &preferences)> + GetWidgetsPreferencesDelegate; + + typedef DPL::FastDelegate<void (const ResourcesPreferences &preferences)> + GetResourcesPreferencesDelegate; + + virtual void setWidgetPreference(const std::string &resource, + const std::string &widget, + const AceDB::PreferenceTypes &preference) = 0; + + virtual void setResourcePreference(const std::string &resource, + const AceDB::PreferenceTypes &preference) = 0; + + virtual void asyncGetWidgetsPreferences( + GetWidgetsPreferencesDelegate delegate) = 0; + + virtual void asyncGetResourcesPreferences( + GetResourcesPreferencesDelegate delegate) = 0; + + virtual void resetWidgetsPreferences() = 0; + virtual void resetResourcesPreferences() = 0; + + virtual ~IClient() + { + } +}; +} // namespace AceSettings + +#endif // WRT_SRC_UI_SHARED_GADGET_IACESETTINGSCLIENT_H_ diff --git a/src/security/i_ace_settings_server.h b/src/security/i_ace_settings_server.h new file mode 100644 index 0000000..3cce315 --- /dev/null +++ b/src/security/i_ace_settings_server.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file i_ace_settings_server.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This is a header of server of ACE user preferences + */ +#ifndef WRT_SRC_ACCESS_CONTROL_IPC_SETTINGS_I_ACE_SETTINGS_SERVER_H_ +#define WRT_SRC_ACCESS_CONTROL_IPC_SETTINGS_I_ACE_SETTINGS_SERVER_H_ + +class IAceSettingsServer +{ + public: + virtual ~IAceSettingsServer() + { + } + + protected: + IAceSettingsServer() + { + } +}; + +#endif // WRT_SRC_ACCESS_CONTROL_IPC_SETTINGS_I_ACE_SETTINGS_SERVER_H_ diff --git a/src/security/security_controller.cpp b/src/security/security_controller.cpp new file mode 100644 index 0000000..762a640 --- /dev/null +++ b/src/security/security_controller.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * This class simply redirects the access requests to access control engine. + * The aim is to hide access control engine specific details from WRT modules. + * It also implements WRT_INTERFACE.h interfaces, so that ACE could access + * WRT specific and other information during the decision making. + * + * @file security_controller.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Ming Jin(ming79.jin@samsung.com) + * @version 1.0 + * @brief Implementation file for security controller + */ +#include <security_controller.h> + +#include <dpl/ace/PolicyEnforcementPoint.h> +#include <dpl/ace/WRT_INTERFACE.h> +#include <dpl/ace/PolicyEvaluatorFactory.h> +#include <dpl/singleton_impl.h> +#include <dpl/log/log.h> + +#include <attribute_facade.h> +#include <security_logic.h> + +IMPLEMENT_SINGLETON(SecurityController) + +struct SecurityController::Impl +{ + SecurityLogic logic; +}; + +SecurityController::SecurityController() +{ + m_impl.Reset(new Impl); +} + +SecurityController::~SecurityController() +{ +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::InitializeSyncEvent & /* event */) +{ + m_impl->logic.initialize(); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::TerminateSyncEvent & /*event*/) +{ + m_impl->logic.terminate(); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::AuthorizeWidgetInstallEvent &event) +{ + m_impl->logic.authorizeWidgetInstall(event.GetArg0(), event.GetArg1()); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::CheckFunctionCallSyncEvent &ev) +{ + *ev.GetArg0() = m_impl->logic.checkFunctionCall(ev.GetArg1()); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::SetWidgetPreferenceEvent & /*event*/) +{ +// m_impl->logic.setWidgetPreference(event.GetArg0(), +// event.GetArg1(), +// event.GetArg2()); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::SetResourcePreferenceEvent & /*event*/) +{ +// m_impl->logic.setResourcePreference(event.GetArg0(), event.GetArg1()); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::GetWidgetsPreferencesSyncEvent & /*event*/) +{ +// *event.GetArg0() = m_impl->logic.getWidgetsPreferences(); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::GetResourcesPreferencesSyncEvent & /*event*/) +{ +// *event.GetArg0() = m_impl->logic.getResourcesPreferences(); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::ResetWidgetsPreferencesEvent & /*evt*/) +{ +// m_impl->logic.resetWidgetsPreferences(); +} + +void SecurityController::OnEventReceived( + const SecurityControllerEvents::ResetResourcesPreferencesEvent & /*evt*/) +{ +// m_impl->logic.resetResourcesPreferences(); +} diff --git a/src/security/security_controller.h b/src/security/security_controller.h new file mode 100644 index 0000000..ad0f3d6 --- /dev/null +++ b/src/security/security_controller.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * This class simply redirects the access requests to access control engine. + * The aim is to hide access control engine specific details from WRT modules. + * It also implements WRT_INTERFACE.h interfaces, so that ACE could access + * WRT specific and other information during the decision making. + * + * @file security_controller.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Ming Jin(ming79.jin@samsung.com) + * @version 1.0 + * @brief Header file for security controller + */ +#ifndef SECURITY_CONTROLLER_H +#define SECURITY_CONTROLLER_H + +#include <dpl/singleton.h> +#include <dpl/event/controller.h> +#include <dpl/generic_event.h> +#include <dpl/scoped_ptr.h> +#include <dpl/type_list.h> +#include <string> +#include <ace_settings_logic.h> +#include <dpl/ace-dao-ro/PreferenceTypes.h> +#include <dpl/ace/AbstractPolicyEnforcementPoint.h> + +#include <string> +#include <dpl/event/inter_context_delegate.h> + +#include <dpl/ace-dao-ro/wrt_db_types.h> + +namespace Jobs { +class Job; +} + +namespace SecurityControllerEvents { +DECLARE_GENERIC_EVENT_0(InitializeSyncEvent) +DECLARE_GENERIC_EVENT_0(TerminateSyncEvent) + +DECLARE_GENERIC_EVENT_2(AuthorizeWidgetInstallEvent, + Request *, + AbstractPolicyEnforcementPoint::ResponseReceiver) + +DECLARE_GENERIC_EVENT_2(CheckFunctionCallSyncEvent, + PolicyResult *, + Request *) + +DECLARE_GENERIC_EVENT_3(SetWidgetPreferenceEvent, + std::string, // resource, + WidgetHandle, // subject + AceDB::PreferenceTypes) // preference + +DECLARE_GENERIC_EVENT_2(SetResourcePreferenceEvent, + std::string, // resource, + AceDB::PreferenceTypes) // preference + +DECLARE_GENERIC_EVENT_1(GetWidgetsPreferencesSyncEvent, + AceSettings::WidgetsPreferences *) + +DECLARE_GENERIC_EVENT_1(GetResourcesPreferencesSyncEvent, + AceSettings::ResourcesPreferences *) + +DECLARE_GENERIC_EVENT_0(ResetWidgetsPreferencesEvent) +DECLARE_GENERIC_EVENT_0(ResetResourcesPreferencesEvent) +} // namespace SecurityControllerEvents + +typedef DPL::TypeListDecl< + SecurityControllerEvents::InitializeSyncEvent, + SecurityControllerEvents::TerminateSyncEvent, + SecurityControllerEvents::AuthorizeWidgetInstallEvent, + SecurityControllerEvents::CheckFunctionCallSyncEvent, + SecurityControllerEvents::SetWidgetPreferenceEvent, + SecurityControllerEvents::SetResourcePreferenceEvent, + SecurityControllerEvents::GetWidgetsPreferencesSyncEvent, + SecurityControllerEvents::GetResourcesPreferencesSyncEvent, + SecurityControllerEvents::ResetWidgetsPreferencesEvent, + SecurityControllerEvents::ResetResourcesPreferencesEvent>::Type +SecurityControllerEventsTypeList; + +class SecurityController : + public DPL::Event::Controller<SecurityControllerEventsTypeList> +{ + protected: + virtual void OnEventReceived( + const SecurityControllerEvents::InitializeSyncEvent &event); + virtual void OnEventReceived( + const SecurityControllerEvents::TerminateSyncEvent &event); + virtual void OnEventReceived( + const SecurityControllerEvents::AuthorizeWidgetInstallEvent &event); + virtual void OnEventReceived( + const SecurityControllerEvents::CheckFunctionCallSyncEvent &e); + virtual void OnEventReceived( + const SecurityControllerEvents::SetWidgetPreferenceEvent &event); + virtual void OnEventReceived( + const SecurityControllerEvents::SetResourcePreferenceEvent &event); + virtual void OnEventReceived( + const SecurityControllerEvents::GetWidgetsPreferencesSyncEvent & + event); + virtual void OnEventReceived( + const SecurityControllerEvents::GetResourcesPreferencesSyncEvent & + evt); + virtual void OnEventReceived( + const SecurityControllerEvents::ResetWidgetsPreferencesEvent &evt); + virtual void OnEventReceived( + const SecurityControllerEvents::ResetResourcesPreferencesEvent & + evt); + + private: + class Impl; + DPL::ScopedPtr<Impl> m_impl; + + SecurityController(); + //This desctructor must be in implementation file (cannot be autogenerated) + ~SecurityController(); + + friend class DPL::Singleton<SecurityController>; +}; + +typedef DPL::Singleton<SecurityController> SecurityControllerSingleton; + +#endif // SECURITY_CONTROLLER_H diff --git a/src/security/security_logic.cpp b/src/security/security_logic.cpp new file mode 100644 index 0000000..6485201 --- /dev/null +++ b/src/security/security_logic.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * This class simply redirects the access requests to access control engine. + * The aim is to hide access control engine specific details from WRT modules. + * It also implements WRT_INTERFACE.h interfaces, so that ACE could access + * WRT specific and other information during the decision making. + * + * @file security_controller.h + # @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Ming Jin(ming79.jin@samsung.com) + * @author Piotr Kozbial (p.kozbial@samsung.com) + * @version 1.0 + * @brief Header file for security logic + */ + +#include <dpl/ace/PromptDecision.h> +#include <security_logic.h> +#include <attribute_facade.h> +#ifdef WRT_SMACK_ENABLED +#include <privilege-control.h> +#endif +#include <dpl/wrt-dao-ro/widget_dao_read_only.h> + +void SecurityLogic::initialize() { + m_policyEnforcementPoint.initialize(new WebRuntimeImpl(), + new ResourceInformationImpl(), + new OperationSystemImpl()); +} + +void SecurityLogic::terminate() { + m_policyEnforcementPoint.terminate(); +} + +void SecurityLogic::authorizeWidgetInstall( + Request *request, + AbstractPolicyEnforcementPoint::ResponseReceiver receiver) +{ + PolicyResult result = m_policyEnforcementPoint.check(*request); + + // this is bad idea, what about context in request ?? + // We could resolve problem with memory allocation by adding default + // constructor to Request and pass object by value. + delete request; + + receiver(result); +} + +PolicyResult SecurityLogic::checkFunctionCall(Request* request) +{ + PolicyResult aceResult = m_policyEnforcementPoint.check(*request); + if (aceResult == PolicyEffect::PERMIT) { +#ifdef WRT_SMACK_ENABLED + try { + WrtDB::WidgetDAOReadOnly dao(request->getWidgetHandle()); + DPL::OptionalString pkgName = dao.getPkgname(); + Assert(!pkgName.IsNull() && "widget doesn't have a pkg name"); + const char *devCap = ""; + int ret = grant_rules_forWAC(DPL::ToUTF8String(*pkgName).c_str(), devCap); + Assert(ret==PC_OPERATION_SUCCESS && "smack rules couldn't be granted"); + } catch (WrtDB::WidgetDAOReadOnly::Exception) { + Assert(false && "can't access widget data"); + } +#endif + return PolicyEffect::PERMIT; + } else if (aceResult == PolicyEffect::PROMPT_ONESHOT || + aceResult == PolicyEffect::PROMPT_SESSION || + aceResult == PolicyEffect::PROMPT_BLANKET) + { + // TODO: check stored user answers!!! + // if necessary, grant SMACK rules + // return appropriately - the following is a dummy: + return aceResult; + } else { + return PolicyEffect::DENY; + } +} + +//void SecurityLogic::setWidgetPreference( +// std::string devCap, +// WidgetHandle widgetHandle, +// AceDB::PreferenceTypes preference) +//{ +// m_aceSettingsLogic.setWidgetPreference(devCap, +// widgetHandle, +// preference); +//} +// +//void SecurityLogic::setResourcePreference( +// std::string devCap, +// AceDB::PreferenceTypes preference) +//{ +// m_aceSettingsLogic.setResourcePreference(devCap, preference); +//} +// +//AceSettings::WidgetsPreferences SecurityLogic::getWidgetsPreferences() { +// return m_aceSettingsLogic.getWidgetsPreferences(); +//} +// +//AceSettings::ResourcesPreferences SecurityLogic::getResourcesPreferences() { +// return m_aceSettingsLogic.getResourcesPreferences(); +//} +// +//void SecurityLogic::resetWidgetsPreferences() { +// m_aceSettingsLogic.resetWidgetsPreferences(); +//} +// +//void SecurityLogic::resetResourcesPreferences() { +// m_aceSettingsLogic.resetResourcesPreferences(); +//} diff --git a/src/security/security_logic.h b/src/security/security_logic.h new file mode 100644 index 0000000..12da736 --- /dev/null +++ b/src/security/security_logic.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * This class simply redirects the access requests to access control engine. + * The aim is to hide access control engine specific details from WRT modules. + * It also implements WRT_INTERFACE.h interfaces, so that ACE could access + * WRT specific and other information during the decision making. + * + * @file security_logic.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @author Ming Jin(ming79.jin@samsung.com) + * @author Piotr Kozbial (p.kozbial@samsung.com) + * @version 1.0 + * @brief Header file for security logic + */ +#ifndef SECURITY_LOGIC_H +#define SECURITY_LOGIC_H + +#include <dpl/ace/Request.h> +#include <dpl/ace/PolicyResult.h> +#include <dpl/ace/AbstractPolicyEnforcementPoint.h> +#include <dpl/ace/Preference.h> +#include <i_ace_settings_client.h> +#include <dpl/ace/PolicyEnforcementPoint.h> + +//#include "ace_settings_logic.h" + +/* SecurityLogic + * May only be created and used by SecurityController. + * There may be only one instance. + */ +class SecurityLogic { + public: + SecurityLogic() {} + ~SecurityLogic() {} + // initialize/terminate + /** */ + void initialize(); + /** */ + void terminate(); + // access control checkpoints + /** */ + void authorizeWidgetInstall( + Request *, + AbstractPolicyEnforcementPoint::ResponseReceiver); + /** */ + PolicyResult checkFunctionCall(Request*); + // access control user settings + /** */ +// void setWidgetPreference( +// std::string devCap, +// WidgetHandle widgetHandle, +// AceDB::PreferenceTypes preference); +// /** */ +// void setResourcePreference( +// std::string devCap, +// AceDB::PreferenceTypes preference); + /** */ +// AceSettings::WidgetsPreferences getWidgetsPreferences(); + /** */ +// AceSettings::ResourcesPreferences getResourcesPreferences(); + /** */ +// void resetWidgetsPreferences(); + /** */ +// void resetResourcesPreferences(); + private: + PolicyEnforcementPoint m_policyEnforcementPoint; +// AceSettingsLogic m_aceSettingsLogic; +}; + +#endif // SECURITY_CONTROLLER_H diff --git a/src/security/simple_roaming_agent.cpp b/src/security/simple_roaming_agent.cpp new file mode 100644 index 0000000..587b95c --- /dev/null +++ b/src/security/simple_roaming_agent.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file simple_roaming_agent.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @author Lukasz Marek (l.marek@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief roaming agent + */ + +#include "simple_roaming_agent.h" +#include <vconf.h> +#include <dpl/fast_delegate.h> +#include <dpl/log/log.h> +#include <dpl/singleton_impl.h> +IMPLEMENT_SINGLETON(SimpleRoamingAgent) + +SimpleRoamingAgent::SimpleRoamingAgent() +{ + if (vconf_notify_key_changed( + VCONFKEY_TELEPHONY_SVC_ROAM, + vConfChagedCallback, this) < 0) + { + LogError("Cannot add vconf callback [" << + VCONFKEY_TELEPHONY_SVC_ROAM << "]"); + Assert(false && "Cannot add vconf callback"); + } + + int result = 0; + if (vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &result) != 0) { + LogError("Cannot get current roaming status"); + Assert(false && "Cannot get current roaming status"); + } else { + bool type = (result == VCONFKEY_TELEPHONY_SVC_ROAM_ON); + m_networkType = type ? ROAMING : HOME; + LogInfo("Network type is " << (type ? "ROAMING" : "HOME")); + } + +} + +SimpleRoamingAgent::~SimpleRoamingAgent() +{ + if (vconf_ignore_key_changed( + VCONFKEY_TELEPHONY_SVC_ROAM, + vConfChagedCallback) < 0) + { + LogError("Cannot rm vconf callback [" << + VCONFKEY_TELEPHONY_SVC_ROAM << "]"); + Assert(false && "Cannot remove vconf callback"); + } + +} + +void SimpleRoamingAgent::vConfChagedCallback(keynode_t *keyNode, void *data) +{ + LogInfo("SimpleRoamingAgent::vConfChagedCallback "); + char *key = vconf_keynode_get_name(keyNode); + + if (NULL == key) { + LogWarning("vconf key is null."); + return; + } + SimpleRoamingAgent *agent = static_cast<SimpleRoamingAgent *>(data); + if (NULL == agent) { + LogError("Bad user arg from vconf lib"); + Assert(false && "Bad user arg from vconf lib"); + return; + } + int result = 0; + if (vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &result) != 0) { + LogError("Cannot get current roaming status"); + Assert(false && "Cannot get current roaming status"); + } else { + bool type = (result == VCONFKEY_TELEPHONY_SVC_ROAM_ON); + agent->m_networkType = type ? ROAMING : HOME; + LogInfo("Network type is " << (type ? "ROAMING" : "HOME")); + } +} diff --git a/src/security/simple_roaming_agent.h b/src/security/simple_roaming_agent.h new file mode 100755 index 0000000..65b0bbe --- /dev/null +++ b/src/security/simple_roaming_agent.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file simple_roaming_agent.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief simple roaming agent + */ + +#ifndef WRT_SRC_ACCESS_CONTROL_COMMON_SIMPLE_ROAMING_AGENT_H_ +#define WRT_SRC_ACCESS_CONTROL_COMMON_SIMPLE_ROAMING_AGENT_H_ + +#include <string> +#include <dpl/singleton.h> +#include <dpl/noncopyable.h> +#include <vconf.h> + +class SimpleRoamingAgent : DPL::Noncopyable +{ + public: + bool IsRoamingOn() const + { + return ROAMING == m_networkType; + } + + private: + enum NetworkType {ROAMING, HOME}; + + NetworkType m_networkType; + + SimpleRoamingAgent(); + virtual ~SimpleRoamingAgent(); + + static void vConfChagedCallback(keynode_t *keyNode, void *userParam); + + friend class DPL::Singleton<SimpleRoamingAgent>; +}; + +typedef DPL::Singleton<SimpleRoamingAgent> SimpleRoamingAgentSingleton; + +#endif//WRT_SRC_ACCESS_CONTROL_COMMON_SIMPLE_ROAMING_AGENT_H_ diff --git a/src/wrt-installer/CMakeLists.txt b/src/wrt-installer/CMakeLists.txt new file mode 100644 index 0000000..9065231 --- /dev/null +++ b/src/wrt-installer/CMakeLists.txt @@ -0,0 +1,66 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# +# +# @file CMakeLists.txt +# @author Lukasz Wrzosek (l.wrzosek@samsung.com) +# @version 1.0 +# + +SET(WRT_INSTALLER_DIR + ${INSTALLER_SRC_DIR}/wrt-installer + ) + +SET(WRT_INSTALLER_SOURCES + ${WRT_INSTALLER_DIR}/wrt_installer.cpp + ${WRT_INSTALLER_DIR}/wrt_installer_api.cpp + ${WRT_INSTALLER_DIR}/installer_callbacks_translate.cpp + ${WRT_INSTALLER_DIR}/plugin_utils.cpp + ${WRT_INSTALLER_DIR}/language_subtag_rst_tree.cpp + ${WRT_INSTALLER_DIR}/installer_main_thread.cpp + ${WRT_INSTALLER_DIR}/option_parser.cpp +) + +PKG_CHECK_MODULES(WRT_INSTALLER_DEPS + pkgmgr-installer + libpcrecpp + REQUIRED) + +INCLUDE_DIRECTORIES( + ${WRT_INSTALLER_DEP_INCLUDES} + ${WRT_INSTALLER_INCLUDES} + ${WRT_INSTALLER_DEPS_INCLUDE_DIRS} +) + +ADD_EXECUTABLE(${TARGET_INSTALLER} + ${TARGET_INSTALLER_STATIC_SRC} + ${WRT_INSTALLER_SOURCES} +) + +ADD_DEFINITIONS("-DSEPARATE_INSTALLER_FOR_DAO") # TODO do not use ifdefs! +ADD_DEFINITIONS(${WRT_INSTALLER_DEPS_CFLAGS}) + +TARGET_LINK_LIBRARIES(${TARGET_INSTALLER} + ${TARGET_INSTALLER_STATIC} + ${WRT_INSTALLER_DEPS_LIBRARIES} +) + + +SET_TARGET_PROPERTIES(${TARGET_INSTALLER} PROPERTIES + LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both -Wl" + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON +) + +INSTALL(TARGETS ${TARGET_INSTALLER} DESTINATION bin) diff --git a/src/wrt-installer/installer_callbacks_translate.cpp b/src/wrt-installer/installer_callbacks_translate.cpp new file mode 100644 index 0000000..4be1c06 --- /dev/null +++ b/src/wrt-installer/installer_callbacks_translate.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file api_callbacks_translate.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief Source file for api callbacks translate functions + */ + +#include <installer_callbacks_translate.h> +#include <dpl/log/log.h> + +namespace InstallerCallbacksTranslate { +WrtErrStatus TranslateError(CommonError::Type status) +{ + switch (status) { + case CommonError::WrtSuccess: + return WRT_SUCCESS; + + case CommonError::HandleNotFound: + return WRT_ERROR_HANDLE_NOT_FOUND; + + case CommonError::AlreadyRunning: + return WRT_ERROR_ALREADY_RUNNING; + + case CommonError::InvalidLanguage: + return WRT_ERROR_INVALID_LANGUAGE; + + case CommonError::AlreadyStopped: + return WRT_ERROR_ALREADY_STOPPED; + + case CommonError::StillAuthorizing: + return WRT_ERROR_STILL_AUTHORIZING; + + case CommonError::EarlyKilled: + return WRT_ERROR_EARLY_KILLED; + + case CommonError::AccessDenied: + return WRT_ERROR_ACCESS_DENIED; + + default: + LogError("Untranslatable error: " << status); + return WRT_ERROR_INTERNAL; + } +} + +void StatusCallback(int widget_handle, + CommonError::Type result, + void *data) +{ + LogDebug("StatusCallback called " << widget_handle << " | " << result); + Assert(data != NULL); + + WrtErrStatus error = TranslateError(result); + StatusCallbackStruct* statusCallbackStruct = + static_cast<StatusCallbackStruct*>(data); + + if (statusCallbackStruct->status_callback) { + statusCallbackStruct->status_callback(widget_handle, + error, + statusCallbackStruct->userdata); + } else { + LogInfo("StatusCallback: ignoring NULL callback pointer"); + } + + delete statusCallbackStruct; +} + +// callback for finished install +void installFinishedCallback(void *userParam, + WidgetHandle widget_handle, + Jobs::WidgetInstall::Exceptions::Type status) +{ + Assert(userParam != NULL); + + StatusCallbackStruct *apiStr = + static_cast<StatusCallbackStruct*>(userParam); + + if (apiStr->status_callback) { + // Translate error + WrtErrStatus errorStatus; + + switch (status) { + case Jobs::WidgetInstall::Exceptions::Success: + errorStatus = WRT_SUCCESS; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorInvalidWidgetPackage: + errorStatus = WRT_INSTALLER_ERROR_INVALID_WIDGET_PACKAGE; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorWidgetDoesNotExist: + errorStatus = WRT_INSTALLER_ERROR_WIDGET_DOES_NOT_EXIST; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorFactoryWidget: + errorStatus = WRT_INSTALLER_ERROR_FACTORY_WIDGET; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorAreadyUninstalling: + errorStatus = WRT_INSTALLER_ERROR_ALREADY_UNINSTALLING; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorOutOfDiskSpace: + errorStatus = WRT_INSTALLER_ERROR_OUT_OUT_DISK_SPACE; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorInvalidPackage: + errorStatus = WRT_INSTALLER_ERROR_INVALID_CERTIFICATE; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorAlreadyInstalled: + errorStatus = WRT_INSTALLER_ERROR_ALREADY_INSTALLED; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorInternal: + errorStatus = WRT_INSTALLER_ERROR_INTERNAL; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorNotAllowed: + errorStatus = WRT_INSTALLER_ERROR_NOT_ALLOWED; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorDeferred: + errorStatus = WRT_INSTALLER_ERROR_DEFERRED; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorDatabaseFailure: + errorStatus = WRT_INSTALLER_ERROR_DATABASE_FAILURE; + break; + + case Jobs::WidgetInstall::Exceptions::ErrorUnknown: + errorStatus = WRT_INSTALLER_ERROR_UNKNOWN; + break; + + default: + errorStatus = WRT_INSTALLER_ERROR_UNKNOWN; + break; + } + + // Callback + apiStr->status_callback(widget_handle, errorStatus, apiStr->userdata); + } else { + LogInfo("installFinishedCallback: No callback"); + } +} + +// callback for finished install +void uninstallFinishedCallback(void *userParam, + WidgetHandle widget_handle, + Jobs::WidgetUninstall::Exceptions::Type status) +{ + Assert(userParam != NULL); + + StatusCallbackStruct *apiStr = + static_cast<StatusCallbackStruct*>(userParam); + + if (apiStr->status_callback) { + // Translate error + WrtErrStatus errorStatus; + + switch (status) { + case Jobs::WidgetUninstall::Exceptions::Success: + errorStatus = WRT_SUCCESS; + break; + + // case Jobs::WidgetInstall::Exceptions::ErrorAreadyUninstalling: + // errorStatus = WRT_INSTALLER_ERROR_ALREADY_UNINSTALLING; + // break; + + case Jobs::WidgetUninstall::Exceptions::ErrorDatabaseFailure: + errorStatus = WRT_INSTALLER_ERROR_DATABASE_FAILURE; + break; + + case Jobs::WidgetUninstall::Exceptions::ErrorUnknown: + errorStatus = WRT_INSTALLER_ERROR_UNKNOWN; + break; + + default: + errorStatus = WRT_INSTALLER_ERROR_UNKNOWN; + break; + } + + // Callback + apiStr->status_callback(widget_handle, errorStatus, apiStr->userdata); + } else { + LogInfo("uninstallFinishedCallback: No callback"); + } +} + +void pluginInstallFinishedCallback(void *userParam, + Jobs::PluginInstall::Exceptions::Type status) +{ + Assert(userParam); + + PluginStatusCallbackStruct *apiStr = + static_cast<PluginStatusCallbackStruct*>(userParam); + + if (apiStr->statusCallback) { + // Translate error + WrtErrStatus errorStatus; + + switch (status) { + case Jobs::PluginInstall::Exceptions::Success: + errorStatus = WRT_SUCCESS; + break; + case Jobs::PluginInstall::Exceptions::WrongPluginPath: + errorStatus = WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH; + break; + case Jobs::PluginInstall::Exceptions::MetafileError: + errorStatus = WRT_PLUGIN_INSTALLER_ERROR_METAFILE; + break; + case Jobs::PluginInstall::Exceptions::AlreadyInstalled: + errorStatus = WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED; + break; + case Jobs::PluginInstall::Exceptions::LoadingLibraryError: + errorStatus = WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR; + break; + case Jobs::PluginInstall::Exceptions::InstallationWaiting: + errorStatus = WRT_PLUGIN_INSTALLER_ERROR_WAITING; + break; + default: + errorStatus = WRT_INSTALLER_ERROR_UNKNOWN; + break; + } + + apiStr->statusCallback(errorStatus, apiStr->userdata); + } else { + LogInfo("PluginInstallFinishedCallback: No callback"); + } + + delete apiStr; +} + +// callback for progress of install OR uninstall +void installProgressCallback(void *userParam, + ProgressPercent percent, + const ProgressDescription &description) +{ + Assert(userParam != NULL); + + StatusCallbackStruct *apiStr = + static_cast<StatusCallbackStruct*>(userParam); + + if (apiStr->progress_callback) { + //CALLBACK EXEC + LogInfo("Entered " << percent << "% " << description); + apiStr->progress_callback(static_cast<float>(percent), + description.c_str(), + apiStr->userdata); + } else { + LogInfo("installProgressCallback: ignoring NULL callback pointer"); + } +} + +} //namespace + diff --git a/src/wrt-installer/installer_callbacks_translate.h b/src/wrt-installer/installer_callbacks_translate.h new file mode 100644 index 0000000..87cf668 --- /dev/null +++ b/src/wrt-installer/installer_callbacks_translate.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file api_callbacks_translate.h + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief Header file for api callbacks translate functions + */ +#ifndef WRT_SRC_API_API_CALLBACKS_TRANSLATE_H_ +#define WRT_SRC_API_API_CALLBACKS_TRANSLATE_H_ + +#include <wrt_installer_api.h> +#include <wrt_common_types.h> +#include <widget_install/widget_install_errors.h> +#include <widget_uninstall/widget_uninstall_errors.h> +#include <plugin_install/plugin_installer_errors.h> +#include <job_base.h> + +namespace InstallerCallbacksTranslate { +struct StatusCallbackStruct +{ + void* userdata; + WrtInstallerStatusCallback status_callback; + WrtProgressCallback progress_callback; + + StatusCallbackStruct(void* u, + WrtInstallerStatusCallback s, + WrtProgressCallback p) : + userdata(u), + status_callback(s), + progress_callback(p) + { + } +}; + +struct PluginStatusCallbackStruct +{ + void* userdata; + WrtPluginInstallerStatusCallback statusCallback; + WrtProgressCallback progressCallback; + + PluginStatusCallbackStruct(void* u, + WrtPluginInstallerStatusCallback s, + WrtProgressCallback p) : + userdata(u), + statusCallback(s), + progressCallback(p) + { + } +}; + +void StatusCallback(int widget_handle, + CommonError::Type result, + void *data); + +void installFinishedCallback(void *userParam, + WidgetHandle widget_handle, + Jobs::WidgetInstall::Exceptions::Type status); + +void uninstallFinishedCallback(void *userParam, + WidgetHandle widget_handle, + Jobs::WidgetUninstall::Exceptions::Type status); + +void pluginInstallFinishedCallback(void *userParam, + Jobs::PluginInstall::Exceptions::Type status); + +// callback for progress of install OR uninstall +void installProgressCallback(void *userParam, + ProgressPercent percent, + const ProgressDescription &description); + +} //namespace + +#endif /* WRT_SRC_API_API_CALLBACKS_TRANSLATE_H_ */ diff --git a/src/wrt-installer/installer_main_thread.cpp b/src/wrt-installer/installer_main_thread.cpp new file mode 100755 index 0000000..c984769 --- /dev/null +++ b/src/wrt-installer/installer_main_thread.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file installer_main_thread.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include "installer_main_thread.h" +#include <dpl/assert.h> +#include <dpl/wrt-dao-ro/WrtDatabase.h> +#include <dpl/ace-dao-rw/AceDAO.h> +#include <vcore/VCore.h> +#include <dpl/singleton_impl.h> +#include <dpl/assert.h> +#include <installer_controller.h> +#include <security_controller.h> +#include <dpl/popup/popup_controller.h> +#include <dpl/popup/popup_manager.h> +IMPLEMENT_SINGLETON(InstallerMainThread) + +using namespace WrtDB; +using namespace DPL::Popup; + +InstallerMainThread::InstallerMainThread() : m_attached(false) { +} + +InstallerMainThread::~InstallerMainThread() { + Assert(!m_attached); +} + +void InstallerMainThread::AttachDatabases() +{ + Assert(!m_attached); + // Attach databases + ValidationCore::AttachToThread(); + AceDB::AceDAO::attachToThread(); + WrtDB::WrtDatabase::attachToThread(); + m_attached = true; +} + +void InstallerMainThread::DetachDatabases() +{ + Assert(m_attached); + m_attached = false; + // Detach databases + ValidationCore::DetachFromThread(); + AceDB::AceDAO::detachFromThread(); + WrtDB::WrtDatabase::detachFromThread(); +} + +void InstallerMainThread::TouchArchitecture() +{ + // Touch controller + InstallerControllerSingleton::Instance().Touch(); + SecurityControllerSingleton::Instance().Touch(); + DPL::Popup::PopupControllerSingleton::Instance().Touch(); +} + +void InstallerMainThread::TouchArchitectureOnlyInstaller() +{ + // Touch controller + InstallerControllerSingleton::Instance().Touch(); +} diff --git a/src/wrt-installer/installer_main_thread.h b/src/wrt-installer/installer_main_thread.h new file mode 100755 index 0000000..67c1937 --- /dev/null +++ b/src/wrt-installer/installer_main_thread.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file installer_main_thread.h + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#ifndef INSTALLER_MAINTHREAD_H_ +#define INSTALLER_MAINTHREAD_H_ + +#include <dpl/singleton.h> + +class InstallerMainThread { + public: + void AttachDatabases(); + void DetachDatabases(); + void TouchArchitecture(); + void TouchArchitectureOnlyInstaller(); + + private: + friend class DPL::Singleton<InstallerMainThread>; + + InstallerMainThread(); + virtual ~InstallerMainThread(); + + bool m_attached; +}; + +typedef DPL::Singleton<InstallerMainThread> InstallerMainThreadSingleton; + +#endif /* INSTALLER_MAINTHREAD_H_ */ diff --git a/src/wrt-installer/language_subtag_rst_tree.cpp b/src/wrt-installer/language_subtag_rst_tree.cpp new file mode 100644 index 0000000..119d5c6 --- /dev/null +++ b/src/wrt-installer/language_subtag_rst_tree.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file language_subtag_rst_tree.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ +#include <language_subtag_rst_tree.h> +#include <dpl/log/log.h> +#include <dpl/db/orm.h> +#include <dpl/string.h> +#include <dpl/wrt-dao-ro/global_dao_read_only.h> +#include <iterator> +#include <vector> +#include <ctype.h> +#include <dpl/singleton_impl.h> +IMPLEMENT_SINGLETON(LanguageSubtagRstTree) + +bool LanguageSubtagRstTree::ValidateLanguageTag(const std::string &tag_input) +{ + std::string tag = tag_input; + std::transform(tag.begin(), tag.end(), tag.begin(), &tolower); + + std::vector<DPL::String> parts; + DPL::Tokenize(DPL::FromUTF8String(tag), + '-', + std::back_inserter(parts), + false); + std::vector<DPL::String>::iterator token = parts.begin(); + if (token == parts.end()) { + return false; + } + if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_LANGUAGE)) { + ++token; + } else { + return false; + } + + if (token == parts.end()) { + return true; + } + if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG)) { + ++token; + } + + if (token == parts.end()) { + return true; + } + if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT)) { + ++token; + } + + if (token == parts.end()) { + return true; + } + if (WrtDB::GlobalDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION)) { + ++token; + } + + if (token == parts.end()) { + return true; + } + while (token != parts.end()) { + if (WrtDB::GlobalDAOReadOnly::IsValidSubTag( + *token, RECORD_TYPE_VARIANT)) + { + ++token; + } else { + break; + } + } + + //'u' - unicode extension - only one BCP47 extension is registered. + //TODO: unicode extension should be also validated (l.wrzosek) + if (token == parts.end()) { + return true; + } + if (*token == L"u") { + ++token; + bool one_or_more = false; + while (token != parts.end() && + token->size() > 1 && + token->size() <= 8) { + one_or_more = true; + ++token; + } + if (!one_or_more) { + return false; + } + } + + //'x' - privateuse + if (token == parts.end()) { + return true; + } + if (*token == L"x") { + ++token; + bool one_or_more = false; + while (token != parts.end() && + !token->empty() && + token->size() <= 8) { + one_or_more = true; + ++token; + } + if (!one_or_more) { + return false; + } + } + + if (token == parts.end()) { + return true; + } + + //Try private use now: + token = parts.begin(); + if (*token == L"x") { + ++token; + bool one_or_more = false; + while (token != parts.end() && + !token->empty() && + token->size() <= 8) { + one_or_more = true; + ++token; + } + return one_or_more; + } + + //grandfathered is always rejected + return false; +} + +#define TEST_LANG(str, cond) \ + if (LanguageSubtagRstTreeSingleton::Instance().\ + ValidateLanguageTag(str) == cond) {\ + LogDebug("Good validate status for lang: " << str);\ + } else {\ + LogError("Wrong validate status for lang: " << str\ + << ", should be " << cond);\ + } + +void LanguageSubtagRstTree::Initialize() +{ + /* Temporarily added unit test. Commented out due to performance drop. + TEST_LANG("zh", true); + TEST_LANG("esx-al", true); + TEST_LANG("zh-Hant", true); + TEST_LANG("zh-Hant-CN", true); + TEST_LANG("zh-Hant-CN-x-private1-private2", true); + TEST_LANG("plxxx", false); + TEST_LANG("pl-x-private111", false); + TEST_LANG("x-private1", false); //do not support pure private ones + TEST_LANG("x-private22", false); + TEST_LANG("i-private22", false); //do not support i-* + */ +} + +#undef TEST_LANG diff --git a/src/wrt-installer/language_subtag_rst_tree.h b/src/wrt-installer/language_subtag_rst_tree.h new file mode 100644 index 0000000..b057059 --- /dev/null +++ b/src/wrt-installer/language_subtag_rst_tree.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file language_subtag_rst_tree.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + */ +#ifndef LANGUAGE_SUBTAG_RST_TREE_H +#define LANGUAGE_SUBTAG_RST_TREE_H + +#include <dpl/singleton.h> +#include <dpl/noncopyable.h> +#include <string> +class LanguageSubtagRstTree : DPL::Noncopyable +{ + public: + void Initialize(); + bool ValidateLanguageTag(const std::string &tag); +}; + +typedef DPL::Singleton<LanguageSubtagRstTree> LanguageSubtagRstTreeSingleton; + +enum iana_record_types_e +{ + RECORD_TYPE_LANGUAGE, + RECORD_TYPE_SCRIPT, + RECORD_TYPE_REGION, + RECORD_TYPE_VARIANT, + RECORD_TYPE_GRANDFATHERED, + RECORD_TYPE_REDUNDANT, + RECORD_TYPE_EXTLANG +}; + +#endif //LANGUAGE_SUBTAG_RST_TREE_H diff --git a/src/wrt-installer/option_parser.cpp b/src/wrt-installer/option_parser.cpp new file mode 100644 index 0000000..334fbb4 --- /dev/null +++ b/src/wrt-installer/option_parser.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file option_parser.cpp + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Implementation file for OptionParser. + */ + +#include <vector> +#include <algorithm> +#include <dpl/string.h> +#include "option_parser.h" + +DPL::OptionalString OptionParser::QueryOption(int argc, + char* argv[], + const std::string& name) +{ + DPL::OptionalString result; + + std::vector<std::string> args(argv, (argv + argc)); + + auto it = std::find_if(args.begin(), + args.end(), + [&name](const std::string& option){ + return (option == name); + }); + + if (it != args.end()) + { + std::string value; + while ((++it != args.end()) && !IsOption(*it)) + { + value += *it + " "; + } + result = DPL::FromUTF8String(value); + } + + return result; +} + +bool OptionParser::IsOption(const std::string& name) +{ + return (name.find('-') == 0); +} diff --git a/src/wrt-installer/option_parser.h b/src/wrt-installer/option_parser.h new file mode 100644 index 0000000..599bc59 --- /dev/null +++ b/src/wrt-installer/option_parser.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file option_parser.h + * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) + * @brief Header file for OptionParser. + */ + +#ifndef WRT_INSTALLER_SRC_WRT_INSTALLER_OPTION_PARSER_H_ +#define WRT_INSTALLER_SRC_WRT_INSTALLER_OPTION_PARSER_H_ + +#include <string> +#include <dpl/optional_typedefs.h> + +class OptionParser +{ +public: + static DPL::OptionalString QueryOption(int argc, + char* argv[], + const std::string& name); + +private: + static bool IsOption(const std::string& name); +}; + +#endif diff --git a/src/wrt-installer/plugin_utils.cpp b/src/wrt-installer/plugin_utils.cpp new file mode 100755 index 0000000..18db0eb --- /dev/null +++ b/src/wrt-installer/plugin_utils.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin-utils.cpp + * @author + * @version 1.0 + * @brief Header file for plugin util + */ + +#include "plugin_utils.h" +#include <dpl/semaphore.h> +#include <dpl/exception.h> +#include <dpl/log/log.h> +#include <dpl/wrt-dao-ro/global_config.h> + +using namespace WrtDB; + +namespace PluginUtils { +const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock"; + +bool lockPluginInstallation() +{ + Try { + DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE); + return true; + } + Catch(DPL::Semaphore::Exception::CreateFailed){ + LogError("create"); + return false; + } + Catch(DPL::Semaphore::Exception::Base){ + return false; + } +} + +bool unlockPluginInstallation() +{ + Try { + DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE); + return true; + } + Catch(DPL::Semaphore::Exception::Base){ + return false; + } +} + +bool checkPluginInstallationRequired() +{ + std::string installRequest = + std::string(GlobalConfig::GetPluginInstallInitializerName()); + + FileState::Type installationRequest = + checkFile(installRequest); + + switch (installationRequest) { + case FileState::FILE_EXISTS: + return true; + case FileState::FILE_NOT_EXISTS: + return false; + default: + LogWarning("Opening installation request file failed"); + return false; + } +} + +bool removeInstallationRequiredFlag() +{ + std::string installRequest = + std::string(GlobalConfig::GetPluginInstallInitializerName()); + + return removeFile(installRequest); +} + +//checks if file exists and is regular file +FileState::Type checkFile(const std::string& filename) +{ + struct stat tmp; + + if (-1 == stat(filename.c_str(), &tmp)) { + if (ENOENT == errno) { + return FileState::FILE_NOT_EXISTS; + } + return FileState::FILE_READ_DATA_ERROR; + } else if (!S_ISREG(tmp.st_mode)) { + return FileState::FILE_EXISTS_NOT_REGULAR; + } + return FileState::FILE_EXISTS; +} + +bool removeFile(const std::string& filename) +{ + if (0 != unlink(filename.c_str())) { + return false; + } + + return true; +} +} //namespace PluginUtils diff --git a/src/wrt-installer/plugin_utils.h b/src/wrt-installer/plugin_utils.h new file mode 100755 index 0000000..659e627 --- /dev/null +++ b/src/wrt-installer/plugin_utils.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file plugin-utils.h + * @author + * @version 1.0 + * @brief Header file for plugin util + */ +#ifndef PLUGIN_UTILS_H +#define PLUGIN_UTILS_H + +#include <string> +#include <sys/stat.h> + +namespace PluginUtils { +struct FileState +{ + enum Type + { + FILE_EXISTS, + FILE_EXISTS_NOT_REGULAR, + FILE_NOT_EXISTS, + FILE_READ_DATA_ERROR + }; +}; + +bool lockPluginInstallation(); +bool unlockPluginInstallation(); +bool checkPluginInstallationRequired(); +bool removeInstallationRequiredFlag(); +FileState::Type checkFile(const std::string& filename); +bool removeFile(const std::string& filename); + +} +#endif // PLUGIN_UTILS_H diff --git a/src/wrt-installer/wrt_installer.cpp b/src/wrt-installer/wrt_installer.cpp new file mode 100644 index 0000000..a61292b --- /dev/null +++ b/src/wrt-installer/wrt_installer.cpp @@ -0,0 +1,991 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* @file wrt_installer.cpp + * @version 1.0 + * @brief Implementation file for installer + */ + +#include "wrt_installer.h" +#include "plugin_utils.h" + +#include <cstdlib> +#include <string> +#include <fstream> +#include <unistd.h> +#include <dpl/optional.h> +#include <dpl/scoped_free.h> +#include <dpl/optional_typedefs.h> +#include <dpl/exception.h> +#include <dpl/sstream.h> +#include <vconf.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <dpl/localization/localization_utils.h> +#include <dpl/popup/popup_controller.h> +#include <dpl/optional_typedefs.h> +#include <dpl/string.h> +#include "option_parser.h" + +#define PKGMGR_SEND_SIG(installer, pkg_name, key, val) \ + if(pkgmgr_installer_send_signal(installer, PKG_TYPE, pkg_name, key, val)) {\ + LogDebug("Failed to send signal to pkgmgr"); \ + } +using namespace WrtDB; +namespace { // anonymous +const char AUL_ARG_KEY[] = "widget_arg"; +const char PKGMGR_START_KEY[] = "start"; +const char PKGMGR_END_KEY[] = "end"; +const char PKG_TYPE[] = "wgt"; +const char PKGMGR_PROGRESS_KEY[] = "install_percent"; +const char PKGMGR_OK_VAL[] = "ok"; +const char PKGMGR_FAIL_VAL[] = "fail"; +const char PKGMGR_INSTALL_MSG[] = "Install widget"; +const char PKGMGR_UNINSTALL_MSG[] = "Uninstall widget"; + +const double BASE_LAYOUT_W = 720.0f; +const double BASE_LAYOUT_H = 1280.0f; + +struct PluginInstallerData +{ + void* wrtInstaller; + std::string pluginPath; +}; +} // namespace anonymous + +WrtInstaller::WrtInstaller(int argc, char **argv) : + Application(argc, argv, "backend", false), + DPL::TaskDecl<WrtInstaller>(this), + m_packagePath(), + m_handle(-1), + m_initialized(false), + m_numPluginsToInstall(0), + m_totalPlugins(0), + m_returnStatus(-1), + m_installer(NULL), + m_installByPkgmgr(false), + m_quiet(true), + m_sendSig(false), + m_popup(NULL), + m_startupPluginInstallation(false) +{ + Touch(); + LogDebug("App Created"); +} + +WrtInstaller::~WrtInstaller() +{ + LogDebug("App Finished"); +} + +void WrtInstaller::OnStop() +{ + LogInfo("Stopping Dummy Client"); +} + +void WrtInstaller::OnCreate() +{ + LogInfo("Creating DummyClient"); + + AddStep(&WrtInstaller::initStep); + + std::string arg = m_argv[0]; + + if (arg.empty()) { + return showHelpAndQuit(); + } + + installNewPlugins(); + + if (arg.find("wrt-installer") != std::string::npos) + { + if (m_argc <= 1) { + return showHelpAndQuit(); + } + + arg = m_argv[1]; + + if (arg == "-h" || arg == "--help") { + if (m_argc != 2) { + return showHelpAndQuit(); + } + + // Just show help + showHelpAndQuit(); + } else if (arg == "-p" || arg == "--install-plugins") { + if (m_argc != 2) { + return showHelpAndQuit(); + } + if (!m_startupPluginInstallation) { + AddStep(&WrtInstaller::installPluginsStep); + } else { + LogInfo("Plugin installation alredy started"); + } + } else if (arg == "-i" || arg == "--install") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + + m_packagePath = m_argv[2]; + m_installPolicy = WRT_WIM_POLICY_NEVER_UPDATE; + AddStep(&WrtInstaller::installStep); + } else if (arg == "-iu" || arg == "--install-or-update") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + + m_packagePath = m_argv[2]; + m_installPolicy = WRT_WIM_POLICY_WAC; + AddStep(&WrtInstaller::installStep); + } else if (arg == "-if" || arg == "--install-force") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + + m_packagePath = m_argv[2]; + m_installPolicy = WRT_WIM_POLICY_FORCE_INSTALL; + AddStep(&WrtInstaller::installStep); + } else if (arg == "-inq" || arg == "--install-not-quiet") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + m_quiet = false; + m_packagePath = m_argv[2]; + m_installPolicy = WRT_WIM_POLICY_NEVER_UPDATE; + AddStep(&WrtInstaller::installStep); + } else if (arg == "-u" || arg == "--uninstall") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + + m_handle = atoi(m_argv[2]); + AddStep(&WrtInstaller::uninstallStep); + } else if (arg == "-un" || arg == "--uninstall-name") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + m_name = m_argv[2]; + AddStep(&WrtInstaller::uninstallPkgNameStep); + } else if (arg == "-ug" || arg == "--uninstall-guid") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + m_name = m_argv[2]; + AddStep(&WrtInstaller::uninstallGuidStep); + } else if (arg == "-unq" || arg == "--uninstall-not-quiet") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + m_quiet = false; + m_handle = atoi(m_argv[2]); + AddStep(&WrtInstaller::uninstallStep); + } + else if (arg == "--url") { + if (m_argc < 3) { + return showHelpAndQuit(); + } + m_webAppUrl = m_argv[2]; + + DPL::OptionalString icon = OptionParser::QueryOption(m_argc, + m_argv, + "--icon"); + if (!icon.IsNull()) { + m_webAppIcon = DPL::ToUTF8String(*icon); + } + } + } else if (arg.find("backend") != std::string::npos) { + m_installByPkgmgr = true; + m_quiet = false; + m_sendSig = true; + + m_installer = pkgmgr_installer_new(); + if (!pkgmgr_installer_receive_request(m_installer, m_argc, m_argv)) { + //For package manager + int reqType = pkgmgr_installer_get_request_type(m_installer); + m_quiet = pkgmgr_installer_is_quiet(m_installer); + + switch (reqType) { + case PKGMGR_REQ_INSTALL: + m_packagePath = m_argv[4]; + m_installPolicy = WRT_WIM_POLICY_NEVER_UPDATE; + AddStep(&WrtInstaller::installStep); + break; + case PKGMGR_REQ_UNINSTALL: + m_name = m_argv[4]; + AddStep(&WrtInstaller::uninstallPkgNameStep); + break; + default: + LogDebug("Not available type"); + break; + } + } + } else { + // Launch widget based on application basename + size_t pos = arg.find_last_of('/'); + + if (pos != std::string::npos) { + arg = arg.erase(0, pos + 1); + } + + if (sscanf(arg.c_str(), "%i", &m_handle) != 1) { + printf("failed: invalid widget handle\n"); + return showHelpAndQuit(); + } + + LogDebug("Widget Id: " << m_handle << " (" << arg << ")"); + } + + AddStep(&WrtInstaller::shutdownStep); + DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::PostEvent( + WRTInstallerNS::NextStepEvent()); +} + +void WrtInstaller::OnReset(bundle *b) +{ + const char * bundledVal = bundle_get_val(b, AUL_ARG_KEY); + if (bundledVal != NULL) { + m_bundleValue = bundledVal; + LogInfo("Bundled value for (" << AUL_ARG_KEY << ") key received: " << + m_bundleValue); + } +} + +int WrtInstaller::getReturnStatus() const +{ + if (!m_returnStatus) { + return RE_SUCCESS; + } else { + return RE_FAIL; + } +} + +void WrtInstaller::OnTerminate() +{ + LogDebug("Wrt Shutdown now"); + if (m_initialized) { + wrt_installer_shutdown(); + } + delete m_popup; +} + +void WrtInstaller::showHelpAndQuit() +{ + printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/GUID/PATH]...\n" + "Operate with WebRuntime daemon: install, uninstall" + " and launch widgets.\n" + "Query list of installed widgets and setup up debugging support.\n" + "\n" + "Exactly one option must be selected.\n" + "Mandatory arguments to long options are mandatory for short " + "options too.\n" + " -h, --help show this help\n" + " -p, --install-plugins install plugins\n" + " -i, --install " + "install widget package for given path\n" + " -iu, --install-or-update " + "install or update widget package for given path\n" + " -if, --install-force " + "install forcibly widget package for given path\n" + " -inq, --install-not-quiet " + "install with popup \n" + " -u, --uninstall " + "uninstall widget for given ID\n" + " -un, --uninstall for given package name " + "uninstall widget for given pakcage name\n" + " -ug, --uninstall-guid " + "uninstall widget for given Global Unique IDentifier\n" + " -unq, --uninstall-not-quiet " + "uninstall with popup \n" + " --url " + "URL of the remote page for Web Application installed from browser\n" + " --icon " + "path to the icon for Web Application installed from browser\n" + "\n"); + + Quit(); +} + +void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/) +{ + LogDebug("Quiting"); + + if (m_initialized) { + LogDebug("Wrt Shutdown now"); + SwitchToStep(&WrtInstaller::shutdownStep); + DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::PostEvent( + WRTInstallerNS::NextStepEvent()); + } else { + LogDebug("Quiting application"); + return Quit(); + } +} + +void WrtInstaller::OnEventReceived( + const WRTInstallerNS::NextStepEvent& /*event*/) +{ + LogDebug("Executing next step"); + NextStep(); +} + +void WrtInstaller::OnEventReceived( + const WRTInstallerNS::InstallPluginEvent& /*event*/) +{ + PluginInstallerData* privateData = new PluginInstallerData; + privateData->wrtInstaller = this; + + if (!(*m_pluginsPaths).empty()) { + privateData->pluginPath = (*m_pluginsPaths).front(); + (*m_pluginsPaths).pop_front(); + + wrt_install_plugin(privateData->pluginPath.c_str(), + static_cast<void*>(privateData), + &staticWrtPluginInstallationCallback, + &staticWrtPluginInstallProgressCb); + } +} + +void WrtInstaller::initStep() +{ + wrt_installer_init(this, staticWrtInitCallback); +} + +void WrtInstaller::installStep() +{ + LogDebug("Installing widget ..."); + if (!m_quiet) { + m_popup->init(); + } + DPL::ScopedFree<char> packagePath(canonicalize_file_name( + m_packagePath.c_str())); + wrt_install_widget(packagePath ? packagePath.Get() : m_packagePath.c_str(), + this, &staticWrtStatusCallback, + (!m_quiet || m_installByPkgmgr) + ? &staticWrtInstallProgressCallback : NULL, + m_installPolicy); +} + +void WrtInstaller::installPluginsStep() +{ + LogDebug("Installing plugins ..."); + + if (m_startupPluginInstallation) { + LogInfo("Plugin installation started because new plugin package found"); + } else if (!PluginUtils::lockPluginInstallation()) { + LogError("Failed to open plugin installation lock file" + " Plugins are currently installed by other process"); + staticWrtPluginInstallationCallback(WRT_PLUGIN_INSTALLER_ERROR_LOCK, + this); + return; + } + + std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath()); + + DIR *dir; + dir = opendir(PLUGIN_PATH.c_str()); + + if (!dir) { + return; + } + + LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH); + struct dirent* libdir; + + errno = 0; + + std::list<std::string> pluginsPaths; + + while ((libdir = readdir(dir)) != 0) { + if (strcmp(libdir->d_name, ".") == 0 || + strcmp(libdir->d_name, "..") == 0) + { + continue; + } + + std::string path = PLUGIN_PATH; + path += "/"; + path += libdir->d_name; + + struct stat tmp; + + if (stat(path.c_str(), &tmp) == -1) { + LogError("Failed to open file" << path); + continue; + } + + if (!S_ISDIR(tmp.st_mode)) { + LogError("Not a directory" << path); + continue; + } + + pluginsPaths.push_back(path); + } + + //set nb of plugins to install + //this value indicate how many callbacks are expected + m_numPluginsToInstall = pluginsPaths.size(); + LogInfo("Plugins to install: " << m_numPluginsToInstall); + m_pluginsPaths = pluginsPaths; + + // install geolocation plugin + { + m_numPluginsToInstall++; + (*m_pluginsPaths).push_back(GlobalConfig::GetW3CGeolocationFeatureName()); + } + + m_totalPlugins = m_numPluginsToInstall; + DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent> + ::PostEvent(WRTInstallerNS::InstallPluginEvent()); + + if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { + LogError("Failed to close dir: " << dir); + } +} + +void WrtInstaller::uninstallStep() +{ + LogDebug("Uninstalling widget ..."); + if (!m_quiet) { + m_popup->init(); + } + + wrt_uninstall_widget(m_handle, this, &staticWrtStatusCallback, + (!m_quiet || m_installByPkgmgr) + ? &staticWrtUninstallProgressCallback : NULL); +} + +void WrtInstaller::uninstallPkgNameStep() +{ + LogDebug("Uninstalling widget ..."); + if (!m_quiet) { + m_popup->init(); + } + + WrtErrStatus status = wrt_get_widget_by_pkgname(m_name, &m_handle); + if (status == WRT_SUCCESS) { + LogDebug("Get Widget Handle by package name : " << m_handle); + wrt_uninstall_widget(m_handle, this, &staticWrtStatusCallback, + (!m_quiet || m_installByPkgmgr) + ? &staticWrtUninstallProgressCallback : NULL); + } else { + LogError("Fail to uninstalling widget... "); + m_returnStatus = -1; + DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent( + WRTInstallerNS::QuitEvent()); + } +} + +void WrtInstaller::uninstallGuidStep() +{ + LogDebug("Uninstalling widget ..."); + if (!m_quiet) { + m_popup->init(); + } + + WrtErrStatus status = wrt_get_widget_by_guid(m_name, &m_handle); + if (status == WRT_SUCCESS) { + LogDebug("Get Widget Handle by guid : " << m_handle); + wrt_uninstall_widget(m_handle, this, &staticWrtStatusCallback, + !m_quiet ? &staticWrtUninstallProgressCallback : NULL); + } else { + LogError("Fail to uninstalling widget... "); + m_returnStatus = -1; + DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent( + WRTInstallerNS::QuitEvent()); + } +} + +void WrtInstaller::shutdownStep() +{ + LogDebug("Closing Wrt connection ..."); + if (m_initialized) { + wrt_installer_shutdown(); + m_initialized = false; + DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent( + WRTInstallerNS::QuitEvent()); + } +} + +void WrtInstaller::staticWrtInitCallback(WrtErrStatus status, + void* userdata) +{ + WrtInstaller *This = static_cast<WrtInstaller*>(userdata); + Assert(This); + + if (status == WRT_SUCCESS) { + LogDebug("Init succesfull"); + This->m_initialized = true; + This->m_returnStatus = 0; + + if (!This->m_quiet) { + This->m_popup = new InstallerPopup; + This->m_popup->init(); + } + + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent> + ::PostEvent(WRTInstallerNS::NextStepEvent()); + } else { + LogError("Init unsuccesfull"); + This->m_returnStatus = -1; + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::PostEvent( + WRTInstallerNS::QuitEvent()); + } +} + +void WrtInstaller::staticWrtStatusCallback(int handle, + WrtErrStatus status, + void* userdata) +{ + WrtInstaller *This = static_cast<WrtInstaller*>(userdata); + Assert(This); + + Step current = This->GetCurrentStep(); + DPL::String resultMsg; + std::string printMsg; + + if (current == &WrtInstaller::installStep) + { + resultMsg = DPL::FromUTF8String(PKGMGR_INSTALL_MSG); + printMsg = "installed"; + } else if (current == &WrtInstaller::uninstallStep || + current == &WrtInstaller::uninstallPkgNameStep || + current == &WrtInstaller::uninstallGuidStep) + { + resultMsg = DPL::FromUTF8String(PKGMGR_UNINSTALL_MSG); + printMsg = "uninstalled"; + } + + if (WRT_SUCCESS != status) { + // Failure + LogDebug("Step failed"); + This->m_returnStatus = -1; + + if (This->m_installByPkgmgr) { + PKGMGR_SEND_SIG(This->m_installer, This->m_name.c_str(), + PKGMGR_END_KEY, PKGMGR_FAIL_VAL); + } + + if (!This->m_quiet) { + resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_FAIL_VAL); + This->m_popup->showPopup(This, resultMsg, failResultCallback); + } else { + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent> + ::PostEvent(WRTInstallerNS::QuitEvent()); + } + + switch (status) { + case WRT_INSTALLER_ERROR_INVALID_WIDGET_PACKAGE: + This->m_returnStatus = 1; //this status is specific + printf("failed: invalid widget package\n"); + break; + + case WRT_INSTALLER_ERROR_WIDGET_DOES_NOT_EXIST: + printf("failed: widget package does not exist\n"); + break; + + case WRT_INSTALLER_ERROR_FACTORY_WIDGET: + printf("failed: factory widget\n"); + break; + + case WRT_INSTALLER_ERROR_ALREADY_UNINSTALLING: + printf("failed: already uninstalling\n"); + break; + + case WRT_INSTALLER_ERROR_OUT_OUT_DISK_SPACE: + printf("failed: out of disk space\n"); + break; + + case WRT_INSTALLER_ERROR_INVALID_CERTIFICATE: + printf("failed: invalid certificate\n"); + break; + + case WRT_INSTALLER_ERROR_ALREADY_INSTALLED: + printf("failed: already installed\n"); + break; + + case WRT_INSTALLER_ERROR_INTERNAL: + printf("failed: internal error\n"); + break; + + case WRT_INSTALLER_ERROR_NOT_ALLOWED: + printf("failed: installation or update not allowed; invalid" + " mode\n"); + break; + + case WRT_INSTALLER_ERROR_DEFERRED: + printf("deferred: widget update will continue after the widget" + " has been stopped\n"); + break; + + case WRT_INSTALLER_ERROR_DATABASE_FAILURE: + printf("failed: database failure\n"); + break; + + case WRT_INSTALLER_ERROR_UNKNOWN: + printf("failed: unknown error\n"); + break; + + default: + break; + } + } else { + + printf("%s : %d\n", printMsg.c_str(), handle); + LogDebug("Status succesfull"); + This->m_handle = handle; + This->m_returnStatus = 0; + resultMsg += L" : " + DPL::FromUTF8String(PKGMGR_OK_VAL); + + if (This->m_installByPkgmgr) { + PKGMGR_SEND_SIG(This->m_installer, This->m_name.c_str(), + PKGMGR_END_KEY, PKGMGR_OK_VAL); + } + + if (!This->m_quiet) { + This->m_popup->showPopup(This, resultMsg, showResultCallback); + } else { + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent> + ::PostEvent(WRTInstallerNS::NextStepEvent()); + } + } +} + +void WrtInstaller::staticWrtPluginInstallationCallback(WrtErrStatus status, + void* userdata) +{ + Assert(userdata); + + PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata); + + WrtInstaller *This = static_cast<WrtInstaller*>(data->wrtInstaller); + + std::string path = std::string(data->pluginPath); + delete data; + + This->m_numPluginsToInstall--; + LogDebug("Plugins to install: " << This->m_numPluginsToInstall); + + if (This->m_numPluginsToInstall < 1) { + LogDebug("All plugins installation completed"); + + //remove lock file + if (!PluginUtils::unlockPluginInstallation()) { + LogInfo("Failed to remove installation lock"); + } + + //remove installation request + if (!PluginUtils::removeInstallationRequiredFlag()) { + LogInfo("Failed to remove file initializing plugin installation"); + } + + if (!This->m_quiet) { + elm_progressbar_value_set(This->m_popup->m_progressbar, 100.0); + evas_object_show(This->m_popup->m_popup); + } + + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent> + ::PostEvent(WRTInstallerNS::NextStepEvent()); + } else { + if (!This->m_quiet) { + float percent = (This->m_totalPlugins - This->m_numPluginsToInstall)/(float)This->m_totalPlugins; + elm_progressbar_value_set(This->m_popup->m_progressbar, percent); + evas_object_show(This->m_popup->m_popup); + } + + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>::PostEvent( + WRTInstallerNS::InstallPluginEvent()); + } + + if (WRT_SUCCESS == status) { + This->m_returnStatus = 0; + LogDebug("One plugin Installation succesfull: " << path); + return; + } + + // Failure + LogWarning("One of the plugins installation failed!: " << path); + + if (WRT_PLUGIN_INSTALLER_ERROR_WAITING == status) { + LogInfo("Plugin installation is waiting for dependencies"); + } + + switch (status) { + case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH: + LogError("failed: wrong path to plugin directory\n"); + break; + + case WRT_PLUGIN_INSTALLER_ERROR_METAFILE: + LogError("failed: plugin metafile error\n"); + break; + + case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED: + LogError("failed: plugin already installed\n"); + break; + + case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR: + LogError("failed: plugin library: missing symbols or structures\n"); + break; + + case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN: + LogError("failed: unknown error\n"); + break; + + default: + break; + } +} + +void WrtInstaller::staticWrtPluginInstallProgressCb(float percent, + const char* description, + void* userdata) +{ + PluginInstallerData* data = static_cast<PluginInstallerData*>(userdata); + + std::string path = std::string(data->pluginPath); + + LogInfo("Plugin Installation: " << path << + " progress: " << percent << + "description " << description); +} + +void WrtInstaller::staticWrtInstallProgressCallback(float percent, + const char* description, void* userdata) +{ + WrtInstaller *This = static_cast<WrtInstaller*>(userdata); + std::stringstream percentStr; + LogInfo(" progress: " << percent << + "description " << description); + + if (This->m_installByPkgmgr) { + if (This->m_sendSig) { + std::string desc = description; + size_t index = desc.find(" "); + std::string widgetId = desc.substr(0, index - 1); + This->m_name = desc.substr(index + 1, desc.length() - index); + + PKGMGR_SEND_SIG(This->m_installer, widgetId.c_str(), + PKGMGR_START_KEY, "install"); + PKGMGR_SEND_SIG(This->m_installer, widgetId.c_str(), + "change_pkg_name", This->m_name.c_str()); + + This->m_sendSig = false; + } + LogDebug("Broadcast Progress, pkgname" << This->m_name); + + percentStr << static_cast<int>(percent); + PKGMGR_SEND_SIG(This->m_installer, This->m_name.c_str(), + PKGMGR_PROGRESS_KEY, percentStr.str().c_str()); + } + + if (!This->m_quiet) { + elm_progressbar_value_set(This->m_popup->m_progressbar, percent/100.0); + evas_object_show(This->m_popup->m_popup); + } +} +void WrtInstaller::staticWrtUninstallProgressCallback(float percent, + const char* description, void* userdata) +{ + WrtInstaller *This = static_cast<WrtInstaller*>(userdata); + std::stringstream percentStr; + LogInfo(" progress: " << percent << + "description " << description); + + if (This->m_installByPkgmgr) { + if (This->m_sendSig) { + PKGMGR_SEND_SIG(This->m_installer, This->m_name.c_str(), + PKGMGR_START_KEY, "uninstall"); + This->m_sendSig = false; + } + LogDebug("Broadcast Progress, pkgname" << This->m_name); + + percentStr << static_cast<int>(percent); + PKGMGR_SEND_SIG(This->m_installer, This->m_name.c_str(), + PKGMGR_PROGRESS_KEY, percentStr.str().c_str()); + } + + if (!This->m_quiet) { + elm_progressbar_value_set(This->m_popup->m_progressbar, percent/100.0); + evas_object_show(This->m_popup->m_popup); + } +} + +WrtInstaller::InstallerPopup::InstallerPopup() : + m_win(NULL), + m_popup(NULL), + m_progressbar(NULL) +{ +} + +WrtInstaller::InstallerPopup::~InstallerPopup() +{ + LogDebug("App Finished"); +} + +void WrtInstaller::InstallerPopup::init() +{ + LogDebug("Window Init"); + + // create window + m_win = createWin("wrt-installer"); + + // security popup uses installer window + using namespace DPL::Popup; + PopupControllerSingleton::Instance().setExternalCanvas(m_win); + evas_object_show(m_win); + + // create popup + m_popup = elm_popup_add(m_win); + + // create progressbar + m_progressbar = elm_progressbar_add(m_popup); + elm_object_style_set(m_progressbar, "list_progress"); + elm_progressbar_horizontal_set(m_progressbar, EINA_TRUE); + evas_object_size_hint_align_set(m_progressbar, EVAS_HINT_FILL, + EVAS_HINT_FILL); + evas_object_size_hint_weight_set(m_progressbar, EVAS_HINT_EXPAND, + EVAS_HINT_EXPAND); + elm_popup_content_set(m_popup, m_progressbar); + elm_progressbar_value_set(m_progressbar, 0.0); + evas_object_show(m_progressbar); + + // set progressbar to popup + evas_object_show(m_popup); +} + +Evas_Object* WrtInstaller::InstallerPopup::createWin(const char *name) +{ + Evas_Object *win; + win = elm_win_add(NULL, name, ELM_WIN_DIALOG_BASIC); + + int w, h, x, y; + int ret = 0; + int count; + int rotation = -1; + unsigned char *prop_data = NULL; + double xScale, yScale, scale; + + if (win) { + elm_win_alpha_set(win, EINA_TRUE); + elm_win_title_set(win, name); + elm_win_borderless_set(win, EINA_TRUE); + elm_win_raise(win); + ecore_x_window_geometry_get(ecore_x_window_root_get( + ecore_x_window_focus_get()), + &x, + &y, + &w, + &h); + ret = ecore_x_window_prop_property_get(ecore_x_window_root_get( + ecore_x_window_focus_get()), + ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE, + ECORE_X_ATOM_CARDINAL, 32, &prop_data, &count); + } + if (ret && prop_data) { + Assert(count != sizeof(int)); + memcpy(&rotation, prop_data, sizeof(int)); + } + if (prop_data) { + free(prop_data); + } + evas_object_resize(win, w, h); + + if (rotation != -1) { + elm_win_rotation_with_resize_set(win, rotation); + } + + xScale = (double)w / BASE_LAYOUT_W; + yScale = (double)h / BASE_LAYOUT_H; + scale = xScale < yScale ? xScale : yScale; + elm_scale_set(scale); + + return win; +} + +void WrtInstaller::InstallerPopup::showPopup(void* userdata, + const DPL::String& pkgMsg, + ShowResultCallback callback) +{ + LogDebug("Result Popup Created"); + evas_object_del(m_popup); + m_popup = NULL; + + m_popup = elm_popup_with_buttons_add(m_win, "RESULT", + DPL::ToUTF8String(pkgMsg).c_str(), + 1, "OK", 5, NULL); + evas_object_smart_callback_add(m_popup, "response", callback, userdata); + evas_object_show(m_popup); +} + +void WrtInstaller::showResultCallback(void *data, Evas_Object* /*obj*/, + void* /*event_info*/) +{ + WrtInstaller *This = static_cast<WrtInstaller*>(data); + Assert(This); + + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent> + ::PostEvent(WRTInstallerNS::NextStepEvent()); +} + +void WrtInstaller::failResultCallback(void *data, Evas_Object* /*obj*/, + void* /*event_info*/) +{ + WrtInstaller *This = static_cast<WrtInstaller*>(data); + Assert(This); + + This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent> + ::PostEvent(WRTInstallerNS::QuitEvent()); +} + +void WrtInstaller::installNewPlugins() +{ + LogDebug("Install new plugins"); + + if (!PluginUtils::lockPluginInstallation()) { + LogInfo("Lock NOT created"); + return; + } + + if (!PluginUtils::checkPluginInstallationRequired()) { + LogDebug("Plugin installation not required"); + PluginUtils::unlockPluginInstallation(); + return; + } + + m_startupPluginInstallation = true; + AddStep(&WrtInstaller::installPluginsStep); +} + +int main(int argc, char *argv[]) +{ + // Output on stdout will be flushed after every newline character, + // even if it is redirected to a pipe. This is useful for running + // from a script and parsing output. + // (Standard behavior of stdlib is to use full buffering when + // redirected to a pipe, which means even after an end of line + // the output may not be flushed). + setlinebuf(stdout); + + // enable gl + if (!getenv("ELM_ENGINE")) { + if (setenv("ELM_ENGINE", "gl", 1)) { + LogDebug("Enable gl for HW Accel"); + } + } + + WrtInstaller app(argc, argv); + int ret = app.Exec(); + LogDebug("App returned: " << ret); + ret = app.getReturnStatus(); + LogDebug("WrtInstaller returned: " << ret); + return ret; +} diff --git a/src/wrt-installer/wrt_installer.h b/src/wrt-installer/wrt_installer.h new file mode 100644 index 0000000..c043985 --- /dev/null +++ b/src/wrt-installer/wrt_installer.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file wrt_installer.h + * @version 1.0 + * @brief Implementation file for installer + */ +#ifndef WRT_CLIENT_H +#define WRT_CLIENT_H + +#include <dpl/application.h> +#include <dpl/generic_event.h> +#include <dpl/event/controller.h> +#include <dpl/type_list.h> +#include <dpl/task.h> +#include <dpl/log/log.h> +#include <dpl/string.h> +#include <string> +#include <utilX.h> +#include <wrt_installer_api.h> +#include <pkgmgr_installer.h> + +namespace WRTInstallerNS { //anonymous +DECLARE_GENERIC_EVENT_0(QuitEvent) +DECLARE_GENERIC_EVENT_0(NextStepEvent) +DECLARE_GENERIC_EVENT_0(InstallPluginEvent) +} + +typedef void (*ShowResultCallback)(void *data, Evas_Object *obj, + void *event_info); + +enum ReturnValue +{ + RE_SUCCESS, + RE_FAIL +}; + +class WrtInstaller : + public DPL::Application, + private DPL::Event::Controller<DPL::TypeListDecl< + WRTInstallerNS::QuitEvent, + WRTInstallerNS::NextStepEvent, + WRTInstallerNS::InstallPluginEvent>::Type>, + public DPL::TaskDecl<WrtInstaller> +{ + public: + WrtInstaller(int argc, + char **argv); + virtual ~WrtInstaller(); + + + int getReturnStatus() const; + + class InstallerPopup + { + public: + InstallerPopup(); + virtual ~InstallerPopup(); + + void init(); + Evas_Object* createWin(const char* name); + void showPopup(void* userdata, const DPL::String& pkgMsg, + ShowResultCallback callback); + + Evas_Object* m_win; + Evas_Object* m_popup; + Evas_Object* m_progressbar; + }; + + protected: + virtual void OnStop(); + virtual void OnCreate(); + virtual void OnReset(bundle *b); + virtual void OnTerminate(); + + private: + void showHelpAndQuit(); + + // Events + virtual void OnEventReceived(const WRTInstallerNS::QuitEvent &event); + virtual void OnEventReceived(const WRTInstallerNS::NextStepEvent& event); + virtual void OnEventReceived(const WRTInstallerNS::InstallPluginEvent& event); + + // Installation steps + void initStep(); + void installStep(); + void installNewPlugins(); + void installPluginsStep(); + void uninstallStep(); + void uninstallPkgNameStep(); + void uninstallGuidStep(); + void shutdownStep(); + void registerCallbackStep(); + void queryListStep(); + + + // Static callbacks + static void staticWrtInitCallback(WrtErrStatus status, + void* userdata); + static void staticWrtStatusCallback(int handle, + WrtErrStatus status, + void* userdata); + static void staticWrtPluginInstallationCallback(WrtErrStatus status, + void* userdata); + static void staticWrtPluginInstallProgressCb(float percent, + const char* description, + void* userdata); + static void staticWrtInstallProgressCallback(float percent, + const char* description, + void* userdata); + + static void staticWrtUninstallProgressCallback(float percent, + const char* description, + void* userdata); + + static void showResultCallback(void *data, Evas_Object *obj, + void *event_info); + static void failResultCallback(void *data, Evas_Object *obj, + void *event_info); + + // Private data + wrt_widget_install_mode_e m_installPolicy; + std::string m_bundleValue; + std::string m_packagePath; + int m_handle; + std::string m_name; + bool m_initialized; + size_t m_numPluginsToInstall; + size_t m_totalPlugins; + int m_returnStatus; + //For package manager + pkgmgr_installer *m_installer; + bool m_installByPkgmgr; + bool m_quiet; + bool m_sendSig; + InstallerPopup *m_popup; + bool m_startupPluginInstallation; + std::string m_webAppUrl; + std::string m_webAppIcon; + + typedef std::list<std::string> PluginPathList; + DPL::Optional<PluginPathList> m_pluginsPaths; +}; +#endif // WRT_CLIENT_H diff --git a/src/wrt-installer/wrt_installer_api.cpp b/src/wrt-installer/wrt_installer_api.cpp new file mode 100644 index 0000000..7954f01 --- /dev/null +++ b/src/wrt-installer/wrt_installer_api.cpp @@ -0,0 +1,666 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file wrt_installer_api.cpp + * @author Chung Jihoon (jihoon.chung@samsung.com) + * @version 1.0 + * @brief This file contains definitions of wrt installer api + */ +#include <stdlib.h> +#include <list> +#include <string> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dpl/exception.h> +#include <dpl/log/log.h> +#include <dpl/assert.h> +#include <dpl/sstream.h> +#include <libxml/parser.h> + +#include <wrt_installer_api.h> +#include <installer_callbacks_translate.h> +#include <installer_controller.h> +#include <security_controller.h> +#include <language_subtag_rst_tree.h> +#include <dpl/localization/localization_utils.h> +#include <dpl/wrt-dao-ro/global_config.h> +#include <dpl/utils/widget_version.h> +#include <dpl/popup/popup_manager.h> +#include <dpl/popup/popup_controller.h> +#include <attribute_facade.h> +#include <wrt_type.h> +#include <dpl/localization/w3c_file_localization.h> +#include <dpl/wrt-dao-ro/WrtDatabase.h> +#include <vcore/VCore.h> +#include <installer_main_thread.h> + +using namespace WrtDB; + +#undef TRUE +#undef FALSE +#define TRUE 0 +#define FALSE -1 + +#ifdef __cplusplus + +#define EXPORT_API __attribute__((visibility("default"))) +extern "C" +{ +#endif + inline WidgetUpdateMode::Type translateWidgetUpdateMode( + wrt_widget_update_mode_t updateMode) + { + WidgetUpdateMode::Type result = WidgetUpdateMode::Zero; + + if (updateMode & WRT_WIM_NOT_INSTALLED) { + result = result | WidgetUpdateMode::NotInstalled; + } + + if (updateMode & WRT_WIM_INCOMING_VERSION_NOT_STD) { + result = result | WidgetUpdateMode::IncomingVersionNotStd; + } + + if (updateMode & WRT_WIM_EXISTING_VERSION_NOT_STD) { + result = result | WidgetUpdateMode::ExistingVersionNotStd; + } + + if (updateMode & WRT_WIM_BOTH_VERSIONS_NOT_STD) { + result = result | WidgetUpdateMode::BothVersionsNotStd; + } + + if (updateMode & WRT_WIM_EXISTING_VERSION_OLDER) { + result = result | WidgetUpdateMode::ExistingVersionOlder; + } + + if (updateMode & WRT_WIM_EXISTING_VERSION_EQUAL) { + result = result | WidgetUpdateMode::ExistingVersionEqual; + } + + if (updateMode & WRT_WIM_EXISTING_VERSION_NEWER) { + result = result | WidgetUpdateMode::ExistingVersionNewer; + } + + return result; + } + + const char PLUGIN_INSTALL_SEMAPHORE[] = "/.wrt_plugin_install_lock"; + static int wrt_count_plugin; + + static std::string cutOffFileName(const std::string& path) + { + size_t found = path.find_last_of("/"); + if (found == std::string::npos) { + return path; + } else { + return path.substr(0, found); + } + } + + static bool checkPath(const std::string& path) + { + struct stat st; + if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) { + return true; + } + LogError("Cannot access directory [ " << path << " ]"); + return false; + } + + static bool checkPaths() + { + bool if_ok = true; + if_ok &= (checkPath(cutOffFileName( + GlobalConfig::GetWrtDatabaseFilePath()))); + if (!if_ok) { + LogError( + "Path <" << GlobalConfig::GetWrtDatabaseFilePath() << + "> does not exist."); + } + + if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath())); + if (!if_ok) { + LogError( + "Path <" << GlobalConfig::GetDevicePluginPath() << + "> does not exist."); + } + + if_ok &= (checkPath(GlobalConfig::GetFactoryInstalledWidgetPath())); + if (!if_ok) { + LogError( + "Path <" << GlobalConfig::GetFactoryInstalledWidgetPath() << + "> does not exist."); + } + + if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath())); + if (!if_ok) { + LogError( + "Path <" << GlobalConfig::GetUserInstalledWidgetPath() << + "> does not exist."); + } + return if_ok; + } + + void plugin_install_status_cb(WrtErrStatus status, + void* userparam) + { + Assert(userparam); + + wrt_plugin_data *plugin_data = static_cast<wrt_plugin_data*>(userparam); + + if (--wrt_count_plugin < 1) { + LogDebug("All plugins installation completed"); + + LogDebug("Call SetAllinstallpluginsCallback"); + plugin_data->plugin_installed_cb(plugin_data->user_data); + } + + if (status == WRT_SUCCESS) { + LogInfo( + "plugin installation is successful: " << + plugin_data->plugin_path); + return; + } + + LogError("Fail to install plugin : " << plugin_data->plugin_path); + + switch (status) { + case WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH: + LogError("Failed : Plugin install path is wrong"); + break; + case WRT_PLUGIN_INSTALLER_ERROR_METAFILE: + LogError("Failed : Plugin Metafile Error"); + break; + case WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED: + LogError("Failed : This Plugin is already installed"); + break; + case WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR: + LogError("Failed : Library Error. Missing symbol or structures"); + break; + case WRT_PLUGIN_INSTALLER_ERROR_WAITING: + LogError("Failed : Waiting for plugin dependencies"); + break; + case WRT_PLUGIN_INSTALLER_ERROR_LOCK: + LogError("Failed : Lock Error"); + break; + case WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN: + LogError("Failed : Unkown Error"); + break; + default: + break; + } + } + + void plugin_install_progress_cb(float percent, + const char* description, + void* userdata) + { + char *plugin_path = static_cast<char*>(userdata); + + LogInfo("Install plugin : " << plugin_path << + ", Progress : " << percent << + ", Description : " << description); + } + + EXPORT_API int wrt_installer_init(void *userdata, + WrtInstallerInitCallback callback) + { + // Set DPL/LOG MID + DPL::Log::LogSystemSingleton::Instance().SetTag("WRT"); + + try + { + LogInfo("[WRT-API] INITIALIZING WRT INSTALLER..."); + LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__); + + // Touch InstallerController Singleton + InstallerMainThreadSingleton::Instance().TouchArchitecture(); + + // Check paths + if (!checkPaths()) { + if (callback) { + callback(WRT_ERROR_NO_PATH, userdata); + } + return TRUE; + } + + InstallerMainThreadSingleton::Instance().AttachDatabases(); + + //checking for correct DB version +// if (!WrtDB::WrtDatabase::CheckTableExist(DB_CHECKSUM_STR)) { +// LogError("WRONG VERSION OF WRT DATABASE"); +// Assert(false && "WRONG VERSION OF WRT DATABASE"); +// return FALSE; +// } + LogWarning("Database check not implemented!"); + + LogInfo("Prepare libxml2 to work in multithreaded program."); + xmlInitParser(); + + using namespace DPL::Popup; + // Initialize popup manager + PopupManagerSingleton::Instance().Initialize( + PopupRendererPtr(new PopupRenderer)); + + // Initialize Language Subtag registry + LanguageSubtagRstTreeSingleton::Instance().Initialize(); + LocalizationUtils::Initialize(); + + // Initialize ValidationCore + ValidationCore::VCoreInit( + std::string(GlobalConfig::GetFingerprintListFile()), + std::string(GlobalConfig::GetFingerprintListSchema()), + std::string(GlobalConfig::GetVCoreDatabaseFilePath())); + + // Security Logic initialization + CONTROLLER_POST_SYNC_EVENT( + SecurityController, + SecurityControllerEvents::InitializeSyncEvent()); + + // Installer init + CONTROLLER_POST_SYNC_EVENT( + InstallerController, + InstallerControllerEvents:: + InitializeEvent()); + + // Install deferred widget packages + CONTROLLER_POST_EVENT( + InstallerController, + InstallerControllerEvents:: + InstallDeferredWidgetPackagesEvent()); + + if (callback) { + LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK"); + callback(WRT_SUCCESS, userdata); + } + } + catch (const DPL::Exception& ex) + { + LogError("Internal Error during Init:"); + DPL::Exception::DisplayKnownException(ex); + if (callback) { + callback(WRT_ERROR_INTERNAL, userdata); + } + return FALSE; + } + // OK + return TRUE; + } + + EXPORT_API void wrt_installer_shutdown() + { + try + { + LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER..."); + + // Deinitialize Security Logic + CONTROLLER_POST_SYNC_EVENT( + SecurityController, + SecurityControllerEvents:: + TerminateSyncEvent()); + + // Installer termination + CONTROLLER_POST_SYNC_EVENT( + InstallerController, + InstallerControllerEvents:: + TerminateEvent()); + + InstallerMainThreadSingleton::Instance().DetachDatabases(); + + // Global deinit check + LogInfo("Cleanup libxml2 global values."); + xmlCleanupParser(); + + // Deinitialize popup manager + DPL::Popup::PopupManagerSingleton::Instance().Deinitialize(); + } + catch (const DPL::Exception& ex) + { + LogError("Internal Error during Shutdown:"); + DPL::Exception::DisplayKnownException(ex); + } + } + + EXPORT_API void wrt_install_widget(const char *path, + void* userdata, + WrtInstallerStatusCallback status_cb, + WrtProgressCallback progress_cb, + wrt_widget_update_mode_t update_mode) + { + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + LogInfo("[WRT-API] INSTALL WIDGET: " << path); + // Post installation event + CONTROLLER_POST_EVENT( + InstallerController, + InstallerControllerEvents::InstallWidgetEvent( + path, WidgetInstallationStruct( + InstallerCallbacksTranslate::installFinishedCallback, + InstallerCallbacksTranslate::installProgressCallback, + new InstallerCallbacksTranslate::StatusCallbackStruct( + userdata, status_cb, progress_cb), + translateWidgetUpdateMode(update_mode)))); + } + UNHANDLED_EXCEPTION_HANDLER_END + } + + EXPORT_API void wrt_uninstall_widget(int widget_handle, + void* userdata, + WrtInstallerStatusCallback status_cb, + WrtProgressCallback progress_cb) + { + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + LogInfo("[WRT-API] UNINSTALL WIDGET: " << widget_handle); + // Post uninstallation event + CONTROLLER_POST_EVENT( + InstallerController, + InstallerControllerEvents::UninstallWidgetEvent( + widget_handle, + WidgetUninstallationStruct( + InstallerCallbacksTranslate::uninstallFinishedCallback, + InstallerCallbacksTranslate::installProgressCallback, + new InstallerCallbacksTranslate::StatusCallbackStruct( + userdata, status_cb, progress_cb)))); + } + UNHANDLED_EXCEPTION_HANDLER_END + } + + EXPORT_API void wrt_install_plugin( + const char *pluginDir, + void *user_param, + WrtPluginInstallerStatusCallback status_cb, + WrtProgressCallback progress_cb) + { + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + LogInfo("[WRT-API] INSTALL PLUGIN: " << pluginDir); + //Private data for status callback + //Resource is free in pluginInstallFinishedCallback + InstallerCallbacksTranslate::PluginStatusCallbackStruct* + callbackStruct = + new InstallerCallbacksTranslate::PluginStatusCallbackStruct( + user_param, status_cb, progress_cb); + // Added geolocation feature in FeaturesList DB for installing + // widget using gelocation feature. + // If other strange features are added, it will be changed + // for using all of strange features. + if (strcmp(pluginDir, + GlobalConfig::GetW3CGeolocationFeatureName()) == 0) + { + CONTROLLER_POST_EVENT( + InstallerController, + InstallerControllerEvents::InstallPluginGeolocationEvent( + PluginInstallerStruct( + InstallerCallbacksTranslate:: + pluginInstallFinishedCallback, + InstallerCallbacksTranslate:: + installProgressCallback, callbackStruct))); + } else { + CONTROLLER_POST_EVENT( + InstallerController, + InstallerControllerEvents::InstallPluginEvent( + std::string(pluginDir), + PluginInstallerStruct( + InstallerCallbacksTranslate:: + pluginInstallFinishedCallback, + InstallerCallbacksTranslate:: + installProgressCallback, callbackStruct))); + } + } + UNHANDLED_EXCEPTION_HANDLER_END + } + + EXPORT_API void wrt_install_all_plugins( + WrtAllPluginInstalledCallback installed_cb, + void *user_param) + { + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + std::string installRequest = + std::string(GlobalConfig::GetPluginInstallInitializerName()); + + LogDebug("Install new plugins"); + + Try { + DPL::Semaphore lock(PLUGIN_INSTALL_SEMAPHORE); + } + Catch(DPL::Semaphore::Exception::Base){ + LogError("Failed to create installation lock"); + return; + } + + struct stat tmp; + + if (-1 == stat(installRequest.c_str(), &tmp) || + !S_ISREG(tmp.st_mode)) + { + if (ENOENT == errno) { + LogDebug("Plugin installation not required"); + + LogDebug("Call SetAllinstallPluginCallback"); + installed_cb(user_param); + + DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE); + return; + } + LogWarning("Opening installation request file failed"); + } + + std::string PLUGIN_PATH = + std::string(GlobalConfig::GetDevicePluginPath()); + + DIR *dir; + dir = opendir(PLUGIN_PATH.c_str()); + if (!dir) { + DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE); + return; + } + + LogInfo("Plugin DIRECTORY IS" << PLUGIN_PATH); + struct dirent* libdir; + + errno = 0; + + std::list<std::string> pluginsPaths; + + while ((libdir = readdir(dir)) != 0) { + if (strcmp(libdir->d_name, ".") == 0 || + strcmp(libdir->d_name, "..") == 0) + { + continue; + } + + std::string path = PLUGIN_PATH; + path += "/"; + path += libdir->d_name; + + struct stat tmp; + + if (stat(path.c_str(), &tmp) == -1) { + LogError("Failed to open file" << path); + continue; + } + + if (!S_ISDIR(tmp.st_mode)) { + LogError("Not a directory" << path); + continue; + } + + pluginsPaths.push_back(path); + } + + wrt_count_plugin = pluginsPaths.size(); + + FOREACH(it, pluginsPaths) { + wrt_plugin_data *plugin_data = new wrt_plugin_data; + + plugin_data->plugin_installed_cb = installed_cb; + plugin_data->plugin_path = const_cast<char*>(it->c_str()); + plugin_data->user_data = user_param; + + wrt_install_plugin( + it->c_str(), static_cast<void*>(plugin_data), + plugin_install_status_cb, + plugin_install_progress_cb); + } + + wrt_install_plugin( + GlobalConfig::GetW3CGeolocationFeatureName(), NULL, NULL, NULL); + + if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) { + LogError("Failed to close dir: " << dir); + } + + if (0 != unlink(installRequest.c_str())) { + LogError("Failed to remove file initializing plugin " + "installation"); + } + + Try { + DPL::Semaphore::Remove(PLUGIN_INSTALL_SEMAPHORE); + } + Catch(DPL::Semaphore::Exception::Base){ + LogInfo("Failed to remove installation lock"); + } + } + UNHANDLED_EXCEPTION_HANDLER_END + } + + EXPORT_API int wrt_installer_init_for_tests(void *userdata, + WrtInstallerInitCallback callback) + { + // Set DPL/LOG MID + DPL::Log::LogSystemSingleton::Instance().SetTag("WRT"); + + try + { + LogInfo("[WRT-API] INITIALIZING WRT INSTALLER..."); + LogInfo("[WRT-API] BUILD: " << __TIMESTAMP__); + + // Touch InstallerController Singleton + InstallerMainThreadSingleton::Instance(). + TouchArchitectureOnlyInstaller(); + + // Check paths + if (!checkPaths()) { + if (callback) { + callback(WRT_ERROR_NO_PATH, userdata); + } + return TRUE; + } + + CONTROLLER_POST_SYNC_EVENT( + InstallerController, + InstallerControllerEvents:: + InitializeEvent()); + + if (callback) { + LogInfo("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK"); + callback(WRT_SUCCESS, userdata); + } + } + catch (const DPL::Exception& ex) + { + LogError("Internal Error during Init:"); + DPL::Exception::DisplayKnownException(ex); + if (callback) { + callback(WRT_ERROR_INTERNAL, userdata); + } + return FALSE; + } + + // OK + return TRUE; + } + + EXPORT_API void wrt_installer_shutdown_for_tests() + { + try + { + LogInfo("[WRT-API] DEINITIALIZING WRT INSTALLER..."); + + // Installer termination + CONTROLLER_POST_SYNC_EVENT( + InstallerController, + InstallerControllerEvents:: + TerminateEvent()); + + // Global deinit check + LogInfo("Cleanup libxml2 global values."); + xmlCleanupParser(); + } + catch (const DPL::Exception& ex) + { + LogError("Internal Error during Shutdown:"); + DPL::Exception::DisplayKnownException(ex); + } + } + + EXPORT_API WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname, + int *widget_handle) + { + try + { + LogInfo("[WRT-API] GETTING WIDGET HANDLE BY PKG NAME : " + << pkgname); + + WidgetHandle handle = WidgetDAO::getHandle( + DPL::FromASCIIString(pkgname)); + *widget_handle = static_cast<int>(handle); + return WRT_SUCCESS; + } + catch (WidgetDAOReadOnly::Exception::WidgetNotExist) + { + LogError("Error package name is not found"); + return WRT_ERROR_PKGNAME_NOT_FOUND; + } + catch (const DPL::Exception& ex) + { + LogError("Internal Error during get widget id by package name"); + DPL::Exception::DisplayKnownException(ex); + return WRT_ERROR_INTERNAL; + } + } + + EXPORT_API WrtErrStatus wrt_get_widget_by_guid(const std::string guid, + int *widget_handle) + { + try + { + LogInfo("[WRT-API] GETTING WIDGET HANDLE BY WidgetID : " + << guid); + + WidgetGUID widget_guid = DPL::FromUTF8String(guid); + WidgetHandle handle = WidgetDAO::getHandle(widget_guid); + *widget_handle = static_cast<int>(handle); + return WRT_SUCCESS; + } + catch (WidgetDAOReadOnly::Exception::WidgetNotExist) + { + LogError("Error package name is not found"); + return WRT_ERROR_PKGNAME_NOT_FOUND; + } + catch (const DPL::Exception& ex) + { + LogError("Internal Error during get widget id by package name"); + DPL::Exception::DisplayKnownException(ex); + return WRT_ERROR_INTERNAL; + } + } +#ifdef __cplusplus +} +#endif diff --git a/src/wrt-installer/wrt_installer_api.h b/src/wrt-installer/wrt_installer_api.h new file mode 100755 index 0000000..fe5ca85 --- /dev/null +++ b/src/wrt-installer/wrt_installer_api.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file wrt_installer_api.h + * @author Chung Jihoon (jihoon.chung@samsung.com) + * @version 1.0 + * @brief This file contains declarations of wrt_installer_api + */ + +/* + * @defgroup wrt_engine_group WebRunTime engine Library + * @ingroup internet_FW + * Functions to APIs to access wrt-engine + */ + +#ifndef WRT_INSTALLER_API_H_ +#define WRT_INSTALLER_API_H_ + +#include <string> +#include <stdbool.h> +#include <stddef.h> +#include <wrt_type.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Callback function type invoked after async init function + */ +typedef void (*WrtInstallerInitCallback)(WrtErrStatus status, + void *data); + +/** + * Callback function type invoked after async functions + */ +typedef void (*WrtPluginInstallerStatusCallback)(WrtErrStatus status, + void *data); + +/** + * Callback function type invoked after async functions + */ +typedef void (*WrtInstallerStatusCallback)(int widget_handle, + WrtErrStatus status, + void *data); + +/** + * Callback function type invoked after async functions + */ +typedef void (*WrtProgressCallback)(float percent, + const char *description, + void *data); + +/** + * Callback function type invoked when all plugin installations are finished + */ +typedef void (*WrtAllPluginInstalledCallback)(void *userdata); + +typedef struct +{ + WrtAllPluginInstalledCallback plugin_installed_cb; + char *plugin_path; + void *user_data; +} wrt_plugin_data; + +/** + * @fn int wrt_installer_init(void *userdata, WrtInstallerInitCallback callback) + * @brief Initializes WRT + * + * This method is used to initialize wrt-engine. + * It connects to database, initializes webkit, widget and plugin logic. + * + * @param [in] userdata - User parameters to be passed to the callback + * @param [in] callback - The callback function that is launched, after + * wrt initialization. + * The callback is called in the context of the + * application's main loop. + * + * @return 0 on success, -1 on failure + * + * Sample code: + * @code + * int main (int argc, char *argv[]) + * { + * init_loop(argc, argv); + * printf("Initializing WRT"); + * wrt_init(NULL, &init_cb); + * + * wait_for_wrt_init(); + * printf("Starting tests"); + * + * int status = DPL_TestRunnerSingleton_Instance().ExecTestRunner(argc, + * argv); + * + * wrt_installer_shutdown(); + * quit_loop(); + * return status; + * } + * @endcode + * + * @see wrt_installer_shutdown + */ +typedef enum wrt_widget_install_mode_e +{ + /** + * Raw install bit flags + */ + WRT_WIM_NOT_INSTALLED = (1 << 0), + WRT_WIM_INCOMING_VERSION_NOT_STD = (1 << 1), + WRT_WIM_EXISTING_VERSION_NOT_STD = (1 << 2), + WRT_WIM_BOTH_VERSIONS_NOT_STD = (1 << 3), + WRT_WIM_EXISTING_VERSION_OLDER = (1 << 4), + WRT_WIM_EXISTING_VERSION_EQUAL = (1 << 5), + WRT_WIM_EXISTING_VERSION_NEWER = (1 << 6), + + /** + * Update default policies + */ + + /* Never update policy + */ + WRT_WIM_POLICY_NEVER_UPDATE = WRT_WIM_NOT_INSTALLED, + + /* WAC update policy + */ + WRT_WIM_POLICY_WAC = WRT_WIM_NOT_INSTALLED | + WRT_WIM_EXISTING_VERSION_OLDER, + + /* Always update policy + */ + WRT_WIM_POLICY_ALWAYS_INSTALL = WRT_WIM_NOT_INSTALLED | + WRT_WIM_INCOMING_VERSION_NOT_STD | + WRT_WIM_EXISTING_VERSION_NOT_STD | + WRT_WIM_BOTH_VERSIONS_NOT_STD | + WRT_WIM_EXISTING_VERSION_OLDER | + WRT_WIM_EXISTING_VERSION_EQUAL | + WRT_WIM_EXISTING_VERSION_NEWER, + + /* Force install policy + */ + WRT_WIM_POLICY_FORCE_INSTALL = WRT_WIM_POLICY_ALWAYS_INSTALL +} wrt_widget_update_mode_t; + +int wrt_installer_init(void *userdata, + WrtInstallerInitCallback callback); + +/** + * @fn void wrt_installer_shutdown(void) + * @brief Deinitializes WRT + * + * This method is used to deinitialize wrt-engine. + * It deinitializes widget logic, plugin logic, shuts down connection to + * database, switchs back to single thread and does deinit checks. + * + * @return nothing + * + * Sample code: + * @code + * int main (int argc, char *argv[]) + * { + * init_loop(argc, argv); + * printf("Initializing WRT"); + * wrt_init(NULL, &init_cb); + * + * wait_for_wrt_init(); + * printf("Starting tests"); + * + * int status = DPL_TestRunnerSingleton_Instance().ExecTestRunner(argc, + * argv); + * + * wrt_installer_shutdown(); + * quit_loop(); + * return status; + * } + * @endcode + * + * @see wrt_init + */ +void wrt_installer_shutdown(void); + +/** + * @fn void wrt_install_widget(const char *widget_package_path, + * void *user_parameter, + * WrtInstallerStatusCallback status_callback, + * WrtProgressCallback progress_callback, + * wrt_widget_update_mode_t update_mode); + * + * @brief Installs widget from given path + * + * This method is used to install widget from a given path. + * + * @param [in] widget_package_path Path of the widget package. + * @param [in] user_parameter User parameters to be passed to the callback + * @param [in] status_cb Call to this one will be done at the end of + * operation + * The callback is called in the context of the + * application's + * @param [in] progress_cb Callback function to get data of install + * progress + * If you don't want to get progress data, this + * should be NULL + * @param [in] install_mode Installation mode + * @return Nothing (status returned in callback). + * + * Sample code: + * @code + * wrt_install_widget(path.c_str(), + * NULL, + * install_cb, + * progress_cb, + * WRT_WIM_POLICY_WAC); + * @endcode + * + * @see wrt_installer_uninstall_widget + */ +void wrt_install_widget(const char *path, + void *user_parameter, + WrtInstallerStatusCallback status_callback, + WrtProgressCallback progress_callback, + wrt_widget_update_mode_t update_mode); + +/** + * @fn void wrt_installer_uninstall_widget (int widget_handle, + * void* userdata, + * WrtInstallerStatusCallback cb) + * @brief Uninstalls widget using its id + * + * This method is used to uninstall the widget specified by its handle. + * The callback function is called when the uninstall operation is done. + * + * @param [in] widget_handle - widget id + * @param [in] userdata - user parameters to be passed to the callback + * @param [in] status_cb - Call to this one will be done at the end of + * operation + * The callback is called in the context of the + application's + * @param [in] progress_cb - Callback function to get data of install progress + * If you don't want to get progress data, this + * should be NULL + * + * @return nothing (status returned in callback). + * + * Sample code: + * @code //TODO SAMPLE + * wrt_installer_uninstall_widget( appId, NULL, uninstall_cb, progress_cb); + * @endcode + * + * @see wrt_installer_install_widget + */ +void wrt_uninstall_widget (int widget_handle, + void* userdata, + WrtInstallerStatusCallback status_cb, + WrtProgressCallback progress_cb); + +/** + * @fn void wrt_install_plugin(const char *pluginDirectory, + * void *userData, + * WrtInstallerStatusCallback statusCallback, + * WrtProgressCallback progressCallback) + * + * @brief Installs plugin from given path + * + * This method installs new plugin from specified location and calls a callback + * function when the operation is done. + * + * @param [in] pluginDirectory - plugin directory + * @param [in] userData - user parameters to be passed to the callback + * @param [in] statusCallback - user callback to call after installation + * @param [in] progressCallback - user callback to call when plugin + * installation progress has changed + * + * @return nothing (status returned in callback). + * + * Sample code: + * @code + * wrt_install_plugin("/usr/lib/wrt-plugins/",NULL,NULL,NULL); + * @endcode + * + * @see wrt_install_plugin + */ +void wrt_install_plugin(const char *pluginDirectory, + void *userData, + WrtPluginInstallerStatusCallback statusCallback, + WrtProgressCallback progressCallback); + +/** + * @brief To install plugins for first excution + * + * This method install plugins + * + * @return nothing + */ +void wrt_install_all_plugins(WrtAllPluginInstalledCallback installed_cb, + void *user_param); + +/** + * @brief To initialize for tests + * + * This method is wrt init for tests + * + * @return int + */ +int wrt_installer_init_for_tests(void *userdata, + WrtInstallerInitCallback callback); + +/** + * @brief To shutdown for tests + * + * This method is wrt shutdown for tests + * + * @return int + */ +void wrt_installer_shutdown_for_tests(); + +WrtErrStatus wrt_get_widget_by_pkgname(const std::string pkgname, + int *widget_handle); + +WrtErrStatus wrt_get_widget_by_guid(const std::string guid, + int *widget_handle); +#ifdef __cplusplus +} +#endif + +#endif /* WRT_INSTALLER_API_H_ */ diff --git a/src/wrt-installer/wrt_type.h b/src/wrt-installer/wrt_type.h new file mode 100755 index 0000000..f636395 --- /dev/null +++ b/src/wrt-installer/wrt_type.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file wrt_type.h + * @author jihoon Chung (jihoon.Chung@samsung.com) + * @version 1.0 + * @brief This file contains declarations of wrt api + */ + +/* + * @defgroup wrt_engine_group WebRunTime engine Library + * @ingroup internet_FW + * Functions to APIs to access wrt-engine + */ + +#ifndef WRT_TYPE_H_ +#define WRT_TYPE_H_ + +#include <stdbool.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define WRT_DEPRECATED __attribute__((deprecated)) + +typedef enum +{ + /* Generic success */ + WRT_SUCCESS = 0, /*< Success*/ + WRT_ALREADY_INIT, /*< Wrt already initialized*/ + WRT_UPDATE_NEED, /*< Widget data has been updated*/ + WRT_SHUTDOWN, /*<WRT daemon has been closed*/ + + /* Version result */ + WRT_VERSION_OLD = 128, /*< widget's version is older*/ + WRT_VERSION_NEW, /*< widget's version is latest*/ + WRT_VERSION_EXACT, /*< widget's version the same as in arg*/ + WRT_VERSION_NOT_COMPARABLE, /*< widget's version are not comparable */ + + /* Error result */ + WRT_ERROR_INTERNAL = -128, /*< Internal library error. + Should never occur */ + WRT_ERROR_INVALID_PARAMETER, /*< Invalid parameter value was given + (eg. NULL) */ + WRT_ERROR_HANDLE_NOT_FOUND, /*< Widget handle was not found */ + WRT_ERROR_ID_NOT_FOUND, /*< Widget id was not found */ + WRT_ERROR_PKGNAME_NOT_FOUND, /*< package name was not found */ + WRT_ERROR_ALREADY_RUNNING, /*< Widget is already running */ + WRT_ERROR_ALREADY_STOPPED, /*< Widget is already stopped */ + WRT_ERROR_STILL_AUTHORIZING, /*< Widget is still autorizing and has not + yet finished it */ + WRT_ERROR_EARLY_KILLED, /*< Widget was early killed during launch */ + WRT_ERROR_ACCESS_DENIED, /*< Access denied from ACE */ + WRT_ERROR_NOT_INITIALIZED, /*<Occur if wrt initialization fails*/ + WRT_ERROR_INIT, /*<Occur if wrt initialization fails*/ + WRT_ERROR_CONNECTION, /*<Connectiond error occured*/ + WRT_ERROR_NO_PATH, /*<One of specific directory does not + exist*/ + + /* Installer Errors*/ + WRT_INSTALLER_ERROR_INVALID_WIDGET_PACKAGE, /*< */ + WRT_INSTALLER_ERROR_WIDGET_DOES_NOT_EXIST, /*< */ + WRT_INSTALLER_ERROR_FACTORY_WIDGET, /*< Widget is factory installed, + and cannot be uninstalled */ + WRT_INSTALLER_ERROR_ALREADY_UNINSTALLING, /*< Widget is already being + uninstalled */ + WRT_INSTALLER_ERROR_OUT_OUT_DISK_SPACE, /*< */ + WRT_INSTALLER_ERROR_INVALID_CERTIFICATE, /*< */ + WRT_INSTALLER_ERROR_ALREADY_INSTALLED, /*< Widget is already installed + */ + WRT_INSTALLER_ERROR_INTERNAL, /*< */ + WRT_INSTALLER_ERROR_NOT_ALLOWED, /*< Widget installation or + update not allowed */ + /*< because violation of policy + ocurred */ + WRT_INSTALLER_ERROR_DEFERRED, /*< Widget installation deferred + */ + WRT_INSTALLER_ERROR_DATABASE_FAILURE, /*< Failure in database */ + WRT_INSTALLER_ERROR_UNKNOWN, /*< Temporary error. Try to not + use this. */ + WRT_ERROR_INVALID_LANGUAGE, /*< Widget is not valid in + current locales*/ + + /* Plugin Installer Errors */ + WRT_PLUGIN_INSTALLER_ERROR_WRONG_PATH, /*< Wrong Path to plugin Dir */ + WRT_PLUGIN_INSTALLER_ERROR_METAFILE, /*< Plugin metafile error */ + WRT_PLUGIN_INSTALLER_ERROR_ALREADY_INSTALLED, /*< Plugin already installed*/ + WRT_PLUGIN_INSTALLER_ERROR_LIBRARY_ERROR, /*< Shared library error*/ + WRT_PLUGIN_INSTALLER_ERROR_WAITING, /*< Missing dependencies*/ + WRT_PLUGIN_INSTALLER_ERROR_LOCK, /*< Another installation + in progress or lock file + error*/ + WRT_PLUGIN_INSTALLER_ERROR_UNKNOWN /*< Unknown error*/ +} WrtErrStatus; + +typedef struct +{ + char* id; /**< the widget's id + (read from its config.xml during installation)*/ + char* name; /**< the widget's name + (read from its config.xml during installation)*/ + char* version; /**< the widget's varsion + (read from its config.xml during installation)*/ + char* icon_path; /**< the widget's icon_path + (read from its config.xml during installation)*/ + char* pkg_name; /**< the widget's pkg name */ + + /**< the widget's application storage size */ + size_t application_size; + /**< the widget's data storage size */ + size_t data_size; +} wrt_widget_info; + +typedef struct +{ + char *src; /**< valid path to widget's icon*/ + int width; /**< the width of the icon in pixels*/ + int height; /**< the height of the icon in pixels*/ +} wrt_widget_icon; + +typedef struct +{ + int width; /**< the width of the widget in pixels*/ + int height; /**< the height of the widget in pixels*/ +} wrt_widget_size; + +typedef struct +{ + char *widget_name; /**< the widget's name*/ + wrt_widget_icon *widget_icon; /**< the widget's icon data*/ + wrt_widget_size widget_size; /**< the widget's size data*/ + wrt_widget_info *widget_info; /**< the widget's info data*/ +} wrt_widget_info_data; + + +/** + * @fn inline bool wrt_has_succeded(WrtErrStatus err) + * @brief Checks whether call succeded + * + * This function checks whether call succeded. + * If call succeded it returns TRUE. + * + * @param [in] err WrtErrStatus to check + * + * @return Result of the test + * @retval TRUE - the call was successful + * @retval FALSE - the call failed + * + * Sample code: + * @code + * static void InitCallback(WrtErrStatus status, void *data) + * { + * MyApplication *This = (MyApplication *)(data); + * + * printf("[LAUNCH-WIDGET] init callback"); + * + * if (wrt_has_succeded(status) && status!=WRT_UPDATE_NEED) + * { + * This->InstallAllPlugins(); + * + * if (This->m_argc == 2) + * wrt_install_widget(This->m_argv[1], This, InstallCallback); + * } + * else if(wrt_has_failed(status)) + * printf("[LAUNCH-WIDGET] INITIALIZATION HAS FAILED"); + * } + * @endcode + * + * @see wrt_has_failed + */ +inline bool wrt_has_succeded(WrtErrStatus err) +{ + return (err >= 0); +} + +/** + * @fn inline bool wrt_has_failed(WrtErrStatus err) + * @brief Checks whether call failed + * + * This function checks whether call failed. + * If call failed it returns TRUE. + * + * @param [in] err WrtErrStatus to check + * + * @return Result of the test + * @retval TRUE - the call failed + * @retval FALSE - the call was successful + * + * Sample code: + * @code + * static void InitCallback(WrtErrStatus status, void *data) + * { + * MyApplication *This = (MyApplication *)(data); + * + * printf("[LAUNCH-WIDGET] init callback"); + * + * if (wrt_has_succeded(status) && status!=WRT_UPDATE_NEED) + * { + * This->InstallAllPlugins(); + * + * if (This->m_argc == 2) + * wrt_install_widget(This->m_argv[1], This, InstallCallback); + * } + * else if(wrt_has_failed(status)) + * printf("[LAUNCH-WIDGET] INITIALIZATION HAS FAILED"); + * } + * @endcode + * + * @see wrt_has_succeded + */ +inline bool wrt_has_failed(WrtErrStatus err) +{ + return (err < 0); +} + +namespace CommonError { +enum Type +{ + WrtSuccess, ///< Success + + HandleNotFound, ///< Widget handle was not found + AlreadyRunning, ///< Widget is already running + AlreadyStopped, ///< Widget is already stopped + InvalidLanguage, ///< Widget is invalid in current locales + StillAuthorizing, ///< Widget is still autorizing and has not yet finished it + EarlyKilled, ///< Widget was early killed during launch + AccessDenied, ///< Access denied from ACE + CertificateRevoked, ///< Some certificate was revoked. + /// Widget is not allowed to run. + + Unknown ///< Temporary error. Try to not use this. +}; +} + +#ifdef __cplusplus +} +#endif + +#endif /* WRT_TYPE_H_ */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..e17e70c --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +# +# Test files +# +# Define all WRT tests sources. +# Runner is responsible for runnint it all and +# generating proper output files +# + +ADD_SUBDIRECTORY(config_generator)
\ No newline at end of file diff --git a/tests/config_generator/CMakeLists.txt b/tests/config_generator/CMakeLists.txt new file mode 100644 index 0000000..669ff47 --- /dev/null +++ b/tests/config_generator/CMakeLists.txt @@ -0,0 +1,75 @@ +# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +# +# 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. +# +# @file CMakeLists.txt +# @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) +# @version 1.0 +# @brief +# + +# TODO create and use common test build framework as in wrt. + +PKG_CHECK_MODULES(TEST_DEPS + dpl-efl + dpl-test-efl + libxml-2.0 + REQUIRED + ) + +#target +SET(TARGET_CONFIG_GEN_TEST "wrt-tests-config-gen") + +#sources +FILE(GLOB CONFIG_GEN_TEST_SOURCES + ${PROJECT_SOURCE_DIR}/tests/config_generator/*.cpp + ) + +# includes +INCLUDE_DIRECTORIES( + ${PROJECT_SOURCE_DIR}/src/config_generator/ + ${TEST_DEPS_INCLUDE_DIRS} +) + +# executable +ADD_EXECUTABLE(${TARGET_CONFIG_GEN_TEST} ${CONFIG_GEN_TEST_SOURCES}) + +#libraries +TARGET_LINK_LIBRARIES(${TARGET_CONFIG_GEN_TEST} + ${TARGET_CONFIG_GEN_LIB} + ${TEST_DEPS_LIBRARIES} + ) + +# xml files +FILE(GLOB CONFIG_GEN_XML_FILES + ${PROJECT_SOURCE_DIR}/tests/config_generator/xml/*.xml + ) + +INSTALL(FILES ${CONFIG_GEN_XML_FILES} DESTINATION /opt/apps/config_gen) + +# install +SET_TARGET_PROPERTIES(${TARGET_CONFIG_GEN_TEST} PROPERTIES + BUILD_WITH_INSTALL_RPATH ON + INSTALL_RPATH_USE_LINK_PATH ON +) + +INSTALL(TARGETS ${TARGET_CONFIG_GEN_TEST} + DESTINATION bin + PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE +)
\ No newline at end of file diff --git a/tests/config_generator/TestCases.cpp b/tests/config_generator/TestCases.cpp new file mode 100644 index 0000000..1b7b824 --- /dev/null +++ b/tests/config_generator/TestCases.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file TestCases.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include <dpl/test/test_runner.h> +#include <dpl/binary_queue.h> +#include <dpl/file_output.h> +#include <dpl/file_input.h> +#include <dpl/log/log.h> +#include <dpl/foreach.h> +#include <config_generator.h> +#include <libxml/parser.h> +#include <stdio.h> +#include <list> +#include <string> +#include <unistd.h> +#include <fcntl.h> +#include <memory> + +namespace { + +std::string g_expectedFile; +std::string g_resultFile; + +const char* cNull = NULL; + +} // namespace + +// helper macros +#define TEST_START(name) \ + RUNNER_TEST(name) \ + { \ + g_expectedFile = "/opt/apps/config_gen/" #name ".xml"; \ + g_resultFile = "/opt/apps/config_gen/" #name "_result.xml"; + +#define TEST_END } + +#define CURRENT_TEST() *g_testnames.rbegin() + +namespace { + +// Displays the document in logs +void DisplayResult(ConfigXml::DocumentPtr doc) +{ + DPL::BinaryQueue bq; + doc->Write(bq); + + std::unique_ptr<char[]> buffer(new char[bq.Size()]); + + bq.FlattenConsume(buffer.get(),bq.Size()); + LogInfo("Generated XML:\n\n" << buffer.get()); +} + +// Save the document to file +void SaveResult(ConfigXml::DocumentPtr doc) +{ + remove(g_resultFile.c_str()); + DPL::FileOutput fo(g_resultFile); + doc->Write(fo); + fo.Close(); +} + +void closeFile(int* fd) +{ + close(*fd); +} + +/* + * Simple XML comparison method. Performs simple character by character + * comparison (ignores whitespaces). Sensitive to element order and formatting. + * Does not ignore comments. + */ +void CompareResult() +{ + LogDebug("Comparing " << g_expectedFile << " and " << g_resultFile); + + typedef std::unique_ptr<int,void (*)(int*)> FilePtr; + + // open expected + int efd = TEMP_FAILURE_RETRY( + open(g_expectedFile.c_str(), O_RDONLY | O_NONBLOCK)); + RUNNER_ASSERT_MSG(efd != -1, "Failed to open " << g_expectedFile); + FilePtr efdPtr(&efd, closeFile); + + // open result + int rfd = TEMP_FAILURE_RETRY( + open(g_resultFile.c_str(), O_RDONLY | O_NONBLOCK)); + RUNNER_ASSERT_MSG(rfd != -1, "Failed to open " << g_resultFile); + FilePtr rfdPtr(&rfd, closeFile); + + bool eEOF = false; + bool rEOF = false; + for(;!eEOF && !rEOF;) { + unsigned char eChar; + unsigned char rChar; + + // read expected + do { + if(0 == TEMP_FAILURE_RETRY(read(efd, &eChar, 1))) { + eEOF = true; + break; + } + } while(!isgraph(eChar)); + + // read result + do { + if(0 == TEMP_FAILURE_RETRY(read(rfd, &rChar, 1))) { + rEOF = true; + break; + } + } while(!isgraph(rChar)); + + // compare + if(!eEOF && !rEOF) { + RUNNER_ASSERT_MSG( + eChar == rChar, + "Difference '" << eChar << "' != '" << rChar << "'"); + } + } + RUNNER_ASSERT_MSG(eEOF == rEOF, "Different number of characters"); + + LogDebug("Finished"); +} + +void DisplaySaveAndCompare(ConfigXml::DocumentPtr doc) +{ + DisplayResult(doc); + SaveResult(doc); + CompareResult(); +} + +} // namespace + +TEST_START(test001_basic) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + doc->Add<ConfigXml::WIDGET>("http://example.org/exampleWidget", + "2.0 Beta", + 640, + 480); + DisplaySaveAndCompare(doc); +TEST_END + +TEST_START(test002_basic) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + doc->Add<ConfigXml::WIDGET>("http://example.org/exampleWidget", + "2.0 Beta", + "fullscreen"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test003_name) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::NAME>(cNull); + root->Add<ConfigXml::NAME>("example"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test004_description) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::DESCRIPTION>(cNull); + root->Add<ConfigXml::DESCRIPTION>("description"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test005_author) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::AUTHOR>(cNull, cNull, cNull); + root->Add<ConfigXml::AUTHOR>(cNull, cNull, "Krzysztof Janiak"); + root->Add<ConfigXml::AUTHOR>(cNull, + "k.janiak@samsung.com", + "Krzysztof Janiak"); + root->Add<ConfigXml::AUTHOR>("www.google.pl", + "k.janiak@samsung.com", + "Krzysztof Janiak"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test006_license) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::LICENSE>(cNull, cNull); + root->Add<ConfigXml::LICENSE>(cNull, "Public domain."); + root->Add<ConfigXml::LICENSE>("www.samsung.com", "Apache 2.0"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test007_icon) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::ICON>(cNull); + root->Add<ConfigXml::ICON>("icon.png"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test008_content) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::CONTENT>(cNull); + root->Add<ConfigXml::CONTENT>("index.html"); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test009_feature) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + ConfigXml::ElementPtr feature = root->Add<ConfigXml::FEATURE>( + "http://tizen.org/api/application", + true); + + feature->Add<ConfigXml::PARAM>(cNull, cNull); + feature->Add<ConfigXml::PARAM>("accuracy", cNull); + feature->Add<ConfigXml::PARAM>("accuracy", "low"); + feature->Add<ConfigXml::PARAM>("enabled", false); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test010_preference) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::PREFERENCE>(cNull, cNull); + root->Add<ConfigXml::PREFERENCE>("skin", cNull); + root->Add<ConfigXml::PREFERENCE>("skin", "alien"); + root->Add<ConfigXml::PREFERENCE>("api-key", "f6d3a312f9d742", true); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test011_access) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::ACCESS>("http://www.wp.pl/*"); + root->Add<ConfigXml::ACCESS>("http://onet.pl", true); + DisplaySaveAndCompare(doc); +TEST_END + + +TEST_START(test012_tizen_setting) + ConfigXml::DocumentPtr doc = ConfigXml::Document::Create(); + ConfigXml::ElementPtr root = doc->Add<ConfigXml::WIDGET>(cNull,cNull,cNull); + + root->Add<ConfigXml::TIZEN_SETTING>("rotation-lock","portrait"); + root->Add<ConfigXml::TIZEN_SETTING>("backbutton-presence","disable"); + root->Add<ConfigXml::TIZEN_SETTING>("indicator-presence","disable"); + DisplaySaveAndCompare(doc); +TEST_END diff --git a/tests/config_generator/config_gen_test.cpp b/tests/config_generator/config_gen_test.cpp new file mode 100644 index 0000000..e10634d --- /dev/null +++ b/tests/config_generator/config_gen_test.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/* + * @file config_gen_test.cpp + * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) + * @version 1.0 + */ + +#include <dpl/test/test_runner.h> + +int main (int argc, char *argv[]) +{ + return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, + argv); +} diff --git a/tests/config_generator/xml/test001_basic.xml b/tests/config_generator/xml/test001_basic.xml new file mode 100644 index 0000000..5da8118 --- /dev/null +++ b/tests/config_generator/xml/test001_basic.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets" id="http://example.org/exampleWidget" version="2.0 Beta" height="640" width="480"/>
\ No newline at end of file diff --git a/tests/config_generator/xml/test002_basic.xml b/tests/config_generator/xml/test002_basic.xml new file mode 100644 index 0000000..5e8b8bb --- /dev/null +++ b/tests/config_generator/xml/test002_basic.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets" id="http://example.org/exampleWidget" version="2.0 Beta" viewmodes="fullscreen"/>
\ No newline at end of file diff --git a/tests/config_generator/xml/test003_name.xml b/tests/config_generator/xml/test003_name.xml new file mode 100644 index 0000000..e4d7069 --- /dev/null +++ b/tests/config_generator/xml/test003_name.xml @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <name/> + <name>example</name> +</widget>
\ No newline at end of file diff --git a/tests/config_generator/xml/test004_description.xml b/tests/config_generator/xml/test004_description.xml new file mode 100644 index 0000000..58c4d14 --- /dev/null +++ b/tests/config_generator/xml/test004_description.xml @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <description/> + <description>description</description> +</widget>
\ No newline at end of file diff --git a/tests/config_generator/xml/test005_author.xml b/tests/config_generator/xml/test005_author.xml new file mode 100644 index 0000000..b74a0da --- /dev/null +++ b/tests/config_generator/xml/test005_author.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <author/> + <author>Krzysztof Janiak</author> + <author email="k.janiak@samsung.com">Krzysztof Janiak</author> + <author href="www.google.pl" email="k.janiak@samsung.com">Krzysztof Janiak</author> +</widget> diff --git a/tests/config_generator/xml/test006_license.xml b/tests/config_generator/xml/test006_license.xml new file mode 100644 index 0000000..bf190c0 --- /dev/null +++ b/tests/config_generator/xml/test006_license.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <license/> + <license>Public domain.</license> + <license href="www.samsung.com">Apache 2.0</license> +</widget>
\ No newline at end of file diff --git a/tests/config_generator/xml/test007_icon.xml b/tests/config_generator/xml/test007_icon.xml new file mode 100644 index 0000000..43afca6 --- /dev/null +++ b/tests/config_generator/xml/test007_icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <icon/> + <icon src="icon.png"/> +</widget> diff --git a/tests/config_generator/xml/test008_content.xml b/tests/config_generator/xml/test008_content.xml new file mode 100644 index 0000000..b10be8b --- /dev/null +++ b/tests/config_generator/xml/test008_content.xml @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <content/> + <content src="index.html"/> +</widget> diff --git a/tests/config_generator/xml/test009_feature.xml b/tests/config_generator/xml/test009_feature.xml new file mode 100644 index 0000000..5413b33 --- /dev/null +++ b/tests/config_generator/xml/test009_feature.xml @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <feature name="http://tizen.org/api/application" required="true"> + <param/> + <param name="accuracy"/> + <param name="accuracy" value="low"/> + <param name="enabled" value="false"/> + </feature> +</widget> diff --git a/tests/config_generator/xml/test010_preference.xml b/tests/config_generator/xml/test010_preference.xml new file mode 100644 index 0000000..db88274 --- /dev/null +++ b/tests/config_generator/xml/test010_preference.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <preference/> + <preference name="skin"/> + <preference name="skin" value="alien"/> + <preference name="api-key" value="f6d3a312f9d742" readonly="true"/> +</widget> diff --git a/tests/config_generator/xml/test011_access.xml b/tests/config_generator/xml/test011_access.xml new file mode 100644 index 0000000..c609def --- /dev/null +++ b/tests/config_generator/xml/test011_access.xml @@ -0,0 +1,5 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <access origin="http://www.wp.pl/*"/> + <access origin="http://onet.pl" subdomains="true"/> +</widget> diff --git a/tests/config_generator/xml/test012_tizen_setting.xml b/tests/config_generator/xml/test012_tizen_setting.xml new file mode 100644 index 0000000..9b1f65e --- /dev/null +++ b/tests/config_generator/xml/test012_tizen_setting.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<widget xmlns="http://www.w3.org/ns/widgets"> + <tizen:setting rotation-lock="portrait"/> + <tizen:setting backbutton-presence="disable"/> + <tizen:setting indicator-presence="disable"/> +</widget> |