tizen beta release
authorKibum Kim <kb0929.kim@samsung.com>
Mon, 27 Feb 2012 12:16:50 +0000 (21:16 +0900)
committerKibum Kim <kb0929.kim@samsung.com>
Mon, 27 Feb 2012 12:16:50 +0000 (21:16 +0900)
149 files changed:
CMakeLists.txt [new file with mode: 0644]
debian/DESCRIPTION [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/jobs [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/wrt-installer-dev.install.in [new file with mode: 0644]
debian/wrt-installer.install.in [new file with mode: 0644]
debian/wrt-installer.postinst [new file with mode: 0755]
src/CMakeLists.txt [new file with mode: 0644]
src/DESCRIPTION [new file with mode: 0644]
src/commons/wrt_common_types.h [new file with mode: 0644]
src/commons/wrt_error.h [new file with mode: 0644]
src/config_generator/CMakeLists.txt [new file with mode: 0644]
src/config_generator/config_generator.cpp [new file with mode: 0644]
src/config_generator/config_generator.h [new file with mode: 0644]
src/configuration_parser/WidgetConfigurationManager.cpp [new file with mode: 0644]
src/configuration_parser/WidgetConfigurationManager.h [new file with mode: 0644]
src/configuration_parser/deny_all_parser.cpp [new file with mode: 0644]
src/configuration_parser/deny_all_parser.h [new file with mode: 0644]
src/configuration_parser/element_parser.h [new file with mode: 0644]
src/configuration_parser/ignoring_parser.cpp [new file with mode: 0644]
src/configuration_parser/ignoring_parser.h [new file with mode: 0644]
src/configuration_parser/libiriwrapper.cpp [new file with mode: 0644]
src/configuration_parser/libiriwrapper.h [new file with mode: 0644]
src/configuration_parser/parser_runner.cpp [new file with mode: 0644]
src/configuration_parser/parser_runner.h [new file with mode: 0644]
src/configuration_parser/powder_parser.cpp [new file with mode: 0644]
src/configuration_parser/powder_parser.h [new file with mode: 0644]
src/configuration_parser/root_parser.h [new file with mode: 0644]
src/configuration_parser/widget_parser.cpp [new file with mode: 0644]
src/configuration_parser/widget_parser.h [new file with mode: 0644]
src/jobs/job.cpp [new file with mode: 0644]
src/jobs/job.h [new file with mode: 0644]
src/jobs/job_base.h [new file with mode: 0644]
src/jobs/job_exception_base.h [new file with mode: 0644]
src/jobs/plugin_install/job_plugin_install.cpp [new file with mode: 0644]
src/jobs/plugin_install/job_plugin_install.h [new file with mode: 0644]
src/jobs/plugin_install/plugin_install_task.cpp [new file with mode: 0644]
src/jobs/plugin_install/plugin_install_task.h [new file with mode: 0644]
src/jobs/plugin_install/plugin_installer_context.h [new file with mode: 0644]
src/jobs/plugin_install/plugin_installer_errors.h [new file with mode: 0644]
src/jobs/plugin_install/plugin_installer_struct.h [new file with mode: 0644]
src/jobs/plugin_install/plugin_metafile_reader.cpp [new file with mode: 0644]
src/jobs/plugin_install/plugin_metafile_reader.h [new file with mode: 0644]
src/jobs/plugin_install/plugin_objects.cpp [new file with mode: 0644]
src/jobs/plugin_install/plugin_objects.h [new file with mode: 0644]
src/jobs/widget_install/job_widget_install.cpp [new file with mode: 0644]
src/jobs/widget_install/job_widget_install.h [new file with mode: 0644]
src/jobs/widget_install/languages.def [new file with mode: 0644]
src/jobs/widget_install/task_ace_check.cpp [new file with mode: 0644]
src/jobs/widget_install/task_ace_check.h [new file with mode: 0644]
src/jobs/widget_install/task_certify.cpp [new file with mode: 0644]
src/jobs/widget_install/task_certify.h [new file with mode: 0644]
src/jobs/widget_install/task_db_update.cpp [new file with mode: 0644]
src/jobs/widget_install/task_db_update.h [new file with mode: 0644]
src/jobs/widget_install/task_desktop_file.cpp [new file with mode: 0644]
src/jobs/widget_install/task_desktop_file.h [new file with mode: 0644]
src/jobs/widget_install/task_parental_mode.cpp [new file with mode: 0644]
src/jobs/widget_install/task_parental_mode.h [new file with mode: 0644]
src/jobs/widget_install/task_private_storage.cpp [new file with mode: 0644]
src/jobs/widget_install/task_private_storage.h [new file with mode: 0644]
src/jobs/widget_install/task_smack.cpp [new file with mode: 0644]
src/jobs/widget_install/task_smack.h [new file with mode: 0644]
src/jobs/widget_install/task_unzip.cpp [new file with mode: 0644]
src/jobs/widget_install/task_unzip.h [new file with mode: 0644]
src/jobs/widget_install/task_widget_config.cpp [new file with mode: 0644]
src/jobs/widget_install/task_widget_config.h [new file with mode: 0644]
src/jobs/widget_install/wac_security.cpp [new file with mode: 0644]
src/jobs/widget_install/wac_security.h [new file with mode: 0644]
src/jobs/widget_install/widget_install_context.h [new file with mode: 0644]
src/jobs/widget_install/widget_install_errors.h [new file with mode: 0644]
src/jobs/widget_install/widget_installer_struct.h [new file with mode: 0644]
src/jobs/widget_install/widget_update_info.cpp [new file with mode: 0644]
src/jobs/widget_install/widget_update_info.h [new file with mode: 0644]
src/jobs/widget_uninstall/job_widget_uninstall.cpp [new file with mode: 0644]
src/jobs/widget_uninstall/job_widget_uninstall.h [new file with mode: 0644]
src/jobs/widget_uninstall/task_check.cpp [new file with mode: 0644]
src/jobs/widget_uninstall/task_check.h [new file with mode: 0644]
src/jobs/widget_uninstall/task_db_update.cpp [new file with mode: 0644]
src/jobs/widget_uninstall/task_db_update.h [new file with mode: 0644]
src/jobs/widget_uninstall/task_remove_files.cpp [new file with mode: 0644]
src/jobs/widget_uninstall/task_remove_files.h [new file with mode: 0644]
src/jobs/widget_uninstall/task_smack.cpp [new file with mode: 0644]
src/jobs/widget_uninstall/task_smack.h [new file with mode: 0644]
src/jobs/widget_uninstall/uninstaller_context.h [new file with mode: 0644]
src/jobs/widget_uninstall/widget_uninstall_errors.h [new file with mode: 0644]
src/jobs/widget_uninstall/widget_uninstaller_struct.h [new file with mode: 0644]
src/logic/installer_controller.cpp [new file with mode: 0644]
src/logic/installer_controller.h [new file with mode: 0644]
src/logic/installer_logic.cpp [new file with mode: 0644]
src/logic/installer_logic.h [new file with mode: 0644]
src/misc/feature_logic.cpp [new file with mode: 0644]
src/misc/feature_logic.h [new file with mode: 0644]
src/misc/wac_widget_id.cpp [new file with mode: 0644]
src/misc/wac_widget_id.h [new file with mode: 0644]
src/misc/wrt_powder_info_util.cpp [new file with mode: 0644]
src/misc/wrt_powder_info_util.h [new file with mode: 0644]
src/pkg-manager/CMakeLists.txt [new file with mode: 0755]
src/pkg-manager/DESCRIPTION [new file with mode: 0644]
src/pkg-manager/backendlib.cpp [new file with mode: 0755]
src/security/ace_settings_logic.cpp [new file with mode: 0644]
src/security/ace_settings_logic.h [new file with mode: 0644]
src/security/attribute_facade.cpp [new file with mode: 0644]
src/security/attribute_facade.h [new file with mode: 0644]
src/security/i_ace_permissions.h [new file with mode: 0644]
src/security/i_ace_settings_client.h [new file with mode: 0644]
src/security/i_ace_settings_server.h [new file with mode: 0644]
src/security/security_controller.cpp [new file with mode: 0644]
src/security/security_controller.h [new file with mode: 0644]
src/security/security_logic.cpp [new file with mode: 0644]
src/security/security_logic.h [new file with mode: 0644]
src/security/simple_roaming_agent.cpp [new file with mode: 0644]
src/security/simple_roaming_agent.h [new file with mode: 0755]
src/wrt-installer/CMakeLists.txt [new file with mode: 0644]
src/wrt-installer/installer_callbacks_translate.cpp [new file with mode: 0644]
src/wrt-installer/installer_callbacks_translate.h [new file with mode: 0644]
src/wrt-installer/installer_main_thread.cpp [new file with mode: 0755]
src/wrt-installer/installer_main_thread.h [new file with mode: 0755]
src/wrt-installer/language_subtag_rst_tree.cpp [new file with mode: 0644]
src/wrt-installer/language_subtag_rst_tree.h [new file with mode: 0644]
src/wrt-installer/option_parser.cpp [new file with mode: 0644]
src/wrt-installer/option_parser.h [new file with mode: 0644]
src/wrt-installer/plugin_utils.cpp [new file with mode: 0755]
src/wrt-installer/plugin_utils.h [new file with mode: 0755]
src/wrt-installer/wrt_installer.cpp [new file with mode: 0644]
src/wrt-installer/wrt_installer.h [new file with mode: 0644]
src/wrt-installer/wrt_installer_api.cpp [new file with mode: 0644]
src/wrt-installer/wrt_installer_api.h [new file with mode: 0755]
src/wrt-installer/wrt_type.h [new file with mode: 0755]
tests/CMakeLists.txt [new file with mode: 0644]
tests/config_generator/CMakeLists.txt [new file with mode: 0644]
tests/config_generator/TestCases.cpp [new file with mode: 0644]
tests/config_generator/config_gen_test.cpp [new file with mode: 0644]
tests/config_generator/xml/test001_basic.xml [new file with mode: 0644]
tests/config_generator/xml/test002_basic.xml [new file with mode: 0644]
tests/config_generator/xml/test003_name.xml [new file with mode: 0644]
tests/config_generator/xml/test004_description.xml [new file with mode: 0644]
tests/config_generator/xml/test005_author.xml [new file with mode: 0644]
tests/config_generator/xml/test006_license.xml [new file with mode: 0644]
tests/config_generator/xml/test007_icon.xml [new file with mode: 0644]
tests/config_generator/xml/test008_content.xml [new file with mode: 0644]
tests/config_generator/xml/test009_feature.xml [new file with mode: 0644]
tests/config_generator/xml/test010_preference.xml [new file with mode: 0644]
tests/config_generator/xml/test011_access.xml [new file with mode: 0644]
tests/config_generator/xml/test012_tizen_setting.xml [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d97a407
--- /dev/null
@@ -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 (file)
index 0000000..2b8a593
--- /dev/null
@@ -0,0 +1,2 @@
+!!!options!!! stop
+Debian folder (rules, control etc.)
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..87600b7
--- /dev/null
@@ -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 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..a606c26
--- /dev/null
@@ -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 (file)
index 0000000..e772481
--- /dev/null
@@ -0,0 +1 @@
+usr/bin
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/debian/jobs b/debian/jobs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..af33220
--- /dev/null
@@ -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 (file)
index 0000000..86cd4f5
--- /dev/null
@@ -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 (file)
index 0000000..6a9bf3e
--- /dev/null
@@ -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 (executable)
index 0000000..3b16852
--- /dev/null
@@ -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 (file)
index 0000000..3a3281f
--- /dev/null
@@ -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 (file)
index 0000000..0e8c571
--- /dev/null
@@ -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 (file)
index 0000000..9b80c8a
--- /dev/null
@@ -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 (file)
index 0000000..5a1960a
--- /dev/null
@@ -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 (file)
index 0000000..72b2066
--- /dev/null
@@ -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 (file)
index 0000000..9efe644
--- /dev/null
@@ -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 (file)
index 0000000..8e5e1fa
--- /dev/null
@@ -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 (file)
index 0000000..2441731
--- /dev/null
@@ -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 (file)
index 0000000..fc0ac5e
--- /dev/null
@@ -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 (file)
index 0000000..cffa56a
--- /dev/null
@@ -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 (file)
index 0000000..2d45707
--- /dev/null
@@ -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 (file)
index 0000000..50a74bb
--- /dev/null
@@ -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 (file)
index 0000000..a997f29
--- /dev/null
@@ -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 (file)
index 0000000..9f1f6d5
--- /dev/null
@@ -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 (file)
index 0000000..f429344
--- /dev/null
@@ -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 (file)
index 0000000..1029059
--- /dev/null
@@ -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 (file)
index 0000000..79d5f16
--- /dev/null
@@ -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 (file)
index 0000000..1176165
--- /dev/null
@@ -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 (file)
index 0000000..cb9de64
--- /dev/null
@@ -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 (file)
index 0000000..b56ee5b
--- /dev/null
@@ -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 (file)
index 0000000..3f4a86b
--- /dev/null
@@ -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 (file)
index 0000000..e46b2a7
--- /dev/null
@@ -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 (file)
index 0000000..d008a59
--- /dev/null
@@ -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 (file)
index 0000000..70fef1a
--- /dev/null
@@ -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 (file)
index 0000000..877a966
--- /dev/null
@@ -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 (file)
index 0000000..86e1746
--- /dev/null
@@ -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 (file)
index 0000000..3f12a2d
--- /dev/null
@@ -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 (file)
index 0000000..8bf52ff
--- /dev/null
@@ -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 (file)
index 0000000..a7fde44
--- /dev/null
@@ -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 (file)
index 0000000..218e10b
--- /dev/null
@@ -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 (file)
index 0000000..f3eaa99
--- /dev/null
@@ -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 (file)
index 0000000..026074a
--- /dev/null
@@ -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 (file)
index 0000000..35f0353
--- /dev/null
@@ -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 (file)
index 0000000..ef69d6f
--- /dev/null
@@ -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 (file)
index 0000000..f8b91e5
--- /dev/null
@@ -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 (file)
index 0000000..8de27ed
--- /dev/null
@@ -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 (file)
index 0000000..71e9131
--- /dev/null
@@ -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 (file)
index 0000000..95696d8
--- /dev/null
@@ -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 (file)
index 0000000..114878d
--- /dev/null
@@ -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 (file)
index 0000000..8822978
--- /dev/null
@@ -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 (file)
index 0000000..e26443f
--- /dev/null
@@ -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 (file)
index 0000000..ed87a98
--- /dev/null
@@ -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 (file)
index 0000000..4f9a110
--- /dev/null
@@ -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 (file)
index 0000000..d801066
--- /dev/null
@@ -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 (file)
index 0000000..dbd99bf
--- /dev/null
@@ -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 (file)
index 0000000..0d087c9
--- /dev/null
@@ -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 (file)
index 0000000..6097e35
--- /dev/null
@@ -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 (file)
index 0000000..c0a7b6b
--- /dev/null
@@ -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 (file)
index 0000000..2218168
--- /dev/null
@@ -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 (file)
index 0000000..aad45e0
--- /dev/null
@@ -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 (file)
index 0000000..e3eeec5
--- /dev/null
@@ -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 (file)
index 0000000..f0216e7
--- /dev/null
@@ -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 (file)
index 0000000..e919f6b
--- /dev/null
@@ -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 (file)
index 0000000..f8e679c
--- /dev/null
@@ -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 (file)
index 0000000..e4ba39a
--- /dev/null
@@ -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 (file)
index 0000000..1da1176
--- /dev/null
@@ -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 (file)
index 0000000..3b0de40
--- /dev/null
@@ -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 (file)
index 0000000..8f4710f
--- /dev/null
@@ -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 (file)
index 0000000..0655964
--- /dev/null
@@ -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 (file)
index 0000000..b8ce123
--- /dev/null
@@ -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 (file)
index 0000000..702a8f4
--- /dev/null
@@ -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 (file)
index 0000000..c277dea
--- /dev/null
@@ -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 (file)
index 0000000..5ed746e
--- /dev/null
@@ -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 (file)
index 0000000..33674ad
--- /dev/null
@@ -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 (file)
index 0000000..e0b124c
--- /dev/null
@@ -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 (file)
index 0000000..d08540e
--- /dev/null
@@ -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 (file)
index 0000000..8c1c5b8
--- /dev/null
@@ -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 (file)
index 0000000..ddf3b4e
--- /dev/null
@@ -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 (file)
index 0000000..e1eb8d4
--- /dev/null
@@ -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 (file)
index 0000000..4207726
--- /dev/null
@@ -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 (file)
index 0000000..a7db085
--- /dev/null
@@ -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 (file)
index 0000000..93c4ff2
--- /dev/null
@@ -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 (file)
index 0000000..efde73b
--- /dev/null
@@ -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 (file)
index 0000000..393732b
--- /dev/null
@@ -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 (file)
index 0000000..0d529ca
--- /dev/null
@@ -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 (file)
index 0000000..35a0355
--- /dev/null
@@ -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 (file)
index 0000000..9317654
--- /dev/null
@@ -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 (file)
index 0000000..91173a0
--- /dev/null
@@ -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 (file)
index 0000000..fb7a152
--- /dev/null
@@ -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 (file)
index 0000000..8009b98
--- /dev/null
@@ -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 (file)
index 0000000..8ce43fc
--- /dev/null
@@ -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 (file)
index 0000000..4cb7eb0
--- /dev/null
@@ -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 (file)
index 0000000..db45295
--- /dev/null
@@ -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 (file)
index 0000000..a4e4bd3
--- /dev/null
@@ -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 (file)
index 0000000..550c123
--- /dev/null
@@ -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 (file)
index 0000000..bc1f128
--- /dev/null
@@ -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 (file)
index 0000000..dba5f36
--- /dev/null
@@ -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 (file)
index 0000000..de7bab3
--- /dev/null
@@ -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 (file)
index 0000000..cf5da70
--- /dev/null
@@ -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 (executable)
index 0000000..ea06b72
--- /dev/null
@@ -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 (file)
index 0000000..a9d3696
--- /dev/null
@@ -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 (executable)
index 0000000..85b2f5d
--- /dev/null
@@ -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 (file)
index 0000000..d980f02
--- /dev/null
@@ -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 (file)
index 0000000..fd91399
--- /dev/null
@@ -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 (file)
index 0000000..72db14b
--- /dev/null
@@ -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 (file)
index 0000000..e3a8cfd
--- /dev/null
@@ -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 (file)
index 0000000..3935c9d
--- /dev/null
@@ -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 (file)
index 0000000..d9f6b92
--- /dev/null
@@ -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 (file)
index 0000000..3cce315
--- /dev/null
@@ -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 (file)
index 0000000..762a640
--- /dev/null
@@ -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 (file)
index 0000000..ad0f3d6
--- /dev/null
@@ -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 (file)
index 0000000..6485201
--- /dev/null
@@ -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 (file)
index 0000000..12da736
--- /dev/null
@@ -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 (file)
index 0000000..587b95c
--- /dev/null
@@ -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 (executable)
index 0000000..65b0bbe
--- /dev/null
@@ -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 (file)
index 0000000..9065231
--- /dev/null
@@ -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 (file)
index 0000000..4be1c06
--- /dev/null
@@ -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 (file)
index 0000000..87cf668
--- /dev/null
@@ -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 (executable)
index 0000000..c984769
--- /dev/null
@@ -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 (executable)
index 0000000..67c1937
--- /dev/null
@@ -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 (file)
index 0000000..119d5c6
--- /dev/null
@@ -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 (file)
index 0000000..b057059
--- /dev/null
@@ -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 (file)
index 0000000..334fbb4
--- /dev/null
@@ -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 (file)
index 0000000..599bc59
--- /dev/null
@@ -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 (executable)
index 0000000..18db0eb
--- /dev/null
@@ -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 (executable)
index 0000000..659e627
--- /dev/null
@@ -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 (file)
index 0000000..a61292b
--- /dev/null
@@ -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 (file)
index 0000000..c043985
--- /dev/null
@@ -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 (file)
index 0000000..7954f01
--- /dev/null
@@ -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 (executable)
index 0000000..fe5ca85
--- /dev/null
@@ -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 (executable)
index 0000000..f636395
--- /dev/null
@@ -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 (file)
index 0000000..e17e70c
--- /dev/null
@@ -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 (file)
index 0000000..669ff47
--- /dev/null
@@ -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 (file)
index 0000000..1b7b824
--- /dev/null
@@ -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 (file)
index 0000000..e10634d
--- /dev/null
@@ -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 (file)
index 0000000..5da8118
--- /dev/null
@@ -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 (file)
index 0000000..5e8b8bb
--- /dev/null
@@ -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 (file)
index 0000000..e4d7069
--- /dev/null
@@ -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 (file)
index 0000000..58c4d14
--- /dev/null
@@ -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 (file)
index 0000000..b74a0da
--- /dev/null
@@ -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 (file)
index 0000000..bf190c0
--- /dev/null
@@ -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 (file)
index 0000000..43afca6
--- /dev/null
@@ -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 (file)
index 0000000..b10be8b
--- /dev/null
@@ -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 (file)
index 0000000..5413b33
--- /dev/null
@@ -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 (file)
index 0000000..db88274
--- /dev/null
@@ -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 (file)
index 0000000..c609def
--- /dev/null
@@ -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 (file)
index 0000000..9b1f65e
--- /dev/null
@@ -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>