Initialize Tizen 2.3 tizen_2.3 2.3a_release submit/tizen_2.3/20140531.114548
authorSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 04:20:11 +0000 (13:20 +0900)
committerSehong Na <sehong.na@samsung.com>
Sat, 31 May 2014 04:20:11 +0000 (13:20 +0900)
465 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE [new file with mode: 0644]
build/Options.cmake [new file with mode: 0644]
configuration/CMakeLists.txt [new file with mode: 0644]
configuration/access.xsd [new file with mode: 0644]
configuration/common.xsd [new file with mode: 0644]
configuration/config.xml [new file with mode: 0755]
configuration/feature-wrt.properties [new file with mode: 0644]
configuration/local.xsd [new file with mode: 0644]
configuration/packaging-configuration.xsd [new file with mode: 0755]
configuration/privilege-wrt.properties [new file with mode: 0644]
configuration/signature_schema.xsd [new file with mode: 0644]
configuration/updates.xsd [new file with mode: 0644]
configuration/validate-config.xml.sh [new file with mode: 0755]
configuration/widgets.tizen.xsd [new file with mode: 0755]
configuration/widgets.xsd [new file with mode: 0644]
configuration/xml.xsd [new file with mode: 0644]
packaging/wrt-installer.spec [new file with mode: 0755]
src_mobile/CMakeLists.txt [new file with mode: 0644]
src_mobile/DESCRIPTION [new file with mode: 0644]
src_mobile/commons/installer_log.h [new file with mode: 0644]
src_mobile/commons/wrt_common_types.h [new file with mode: 0644]
src_mobile/commons/wrt_error.h [new file with mode: 0644]
src_mobile/commons/wrt_install_mode.h [new file with mode: 0644]
src_mobile/configuration_parser/deny_all_parser.cpp [new file with mode: 0644]
src_mobile/configuration_parser/deny_all_parser.h [new file with mode: 0644]
src_mobile/configuration_parser/element_parser.h [new file with mode: 0644]
src_mobile/configuration_parser/ignoring_parser.cpp [new file with mode: 0644]
src_mobile/configuration_parser/ignoring_parser.h [new file with mode: 0644]
src_mobile/configuration_parser/libiriwrapper.cpp [new file with mode: 0644]
src_mobile/configuration_parser/libiriwrapper.h [new file with mode: 0644]
src_mobile/configuration_parser/parser_runner.cpp [new file with mode: 0644]
src_mobile/configuration_parser/parser_runner.h [new file with mode: 0644]
src_mobile/configuration_parser/root_parser.h [new file with mode: 0644]
src_mobile/configuration_parser/widget_parser.cpp [new file with mode: 0644]
src_mobile/configuration_parser/widget_parser.h [new file with mode: 0644]
src_mobile/jobs/job.cpp [new file with mode: 0644]
src_mobile/jobs/job.h [new file with mode: 0644]
src_mobile/jobs/job_base.h [new file with mode: 0644]
src_mobile/jobs/job_exception_base.h [new file with mode: 0644]
src_mobile/jobs/job_exception_error.h [new file with mode: 0644]
src_mobile/jobs/job_types.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/job_plugin_install.cpp [new file with mode: 0644]
src_mobile/jobs/plugin_install/job_plugin_install.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_install_task.cpp [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_install_task.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_installer_context.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_installer_errors.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_installer_struct.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_metafile_reader.cpp [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_metafile_reader.h [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_objects.cpp [new file with mode: 0644]
src_mobile/jobs/plugin_install/plugin_objects.h [new file with mode: 0644]
src_mobile/jobs/widget_install/ace_registration.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/ace_registration.h [new file with mode: 0644]
src_mobile/jobs/widget_install/directory_api.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/directory_api.h [new file with mode: 0644]
src_mobile/jobs/widget_install/job_widget_install.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/job_widget_install.h [new file with mode: 0644]
src_mobile/jobs/widget_install/languages.def [new file with mode: 0644]
src_mobile/jobs/widget_install/manifest.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/manifest.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_ace_check.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_ace_check.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_certify.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_certify.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_certify_level.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_certify_level.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_commons.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_commons.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_configuration.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_configuration.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_database.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_database.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_encrypt_resource.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_encrypt_resource.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_file_manipulation.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_file_manipulation.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_install_ospsvc.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_install_ospsvc.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_manifest_file.cpp [new file with mode: 0755]
src_mobile/jobs/widget_install/task_manifest_file.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_pkg_info_update.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_pkg_info_update.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_prepare_files.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_prepare_files.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_prepare_reinstall.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_prepare_reinstall.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_process_config.cpp [new file with mode: 0755]
src_mobile/jobs/widget_install/task_process_config.h [new file with mode: 0755]
src_mobile/jobs/widget_install/task_recovery.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_recovery.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_remove_backup.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_remove_backup.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_smack.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_smack.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_update_files.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_update_files.h [new file with mode: 0644]
src_mobile/jobs/widget_install/task_user_data_manipulation.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/task_user_data_manipulation.h [new file with mode: 0644]
src_mobile/jobs/widget_install/view_mode.h [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_install_context.h [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_install_errors.h [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_installer_struct.h [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_security.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_security.h [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_unzip.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_unzip.h [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_update_info.cpp [new file with mode: 0644]
src_mobile/jobs/widget_install/widget_update_info.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/job_widget_uninstall.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/job_widget_uninstall.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_check.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_check.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_db_update.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_db_update.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_delete_pkginfo.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_delete_pkginfo.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_remove_custom_handlers.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_remove_custom_handlers.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_remove_files.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_remove_files.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_smack.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_smack.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_uninstall_ospsvc.cpp [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/task_uninstall_ospsvc.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/uninstaller_context.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/widget_uninstall_errors.h [new file with mode: 0644]
src_mobile/jobs/widget_uninstall/widget_uninstaller_struct.h [new file with mode: 0644]
src_mobile/logic/installer_controller.cpp [new file with mode: 0644]
src_mobile/logic/installer_controller.h [new file with mode: 0644]
src_mobile/logic/installer_logic.cpp [new file with mode: 0644]
src_mobile/logic/installer_logic.h [new file with mode: 0644]
src_mobile/misc/feature_logic.cpp [new file with mode: 0644]
src_mobile/misc/feature_logic.h [new file with mode: 0644]
src_mobile/misc/libxml_utils.cpp [new file with mode: 0644]
src_mobile/misc/libxml_utils.h [new file with mode: 0644]
src_mobile/misc/plugin_path.cpp [new file with mode: 0644]
src_mobile/misc/plugin_path.h [new file with mode: 0644]
src_mobile/misc/wac_widget_id.cpp [new file with mode: 0644]
src_mobile/misc/wac_widget_id.h [new file with mode: 0644]
src_mobile/misc/widget_install_to_external.cpp [new file with mode: 0644]
src_mobile/misc/widget_install_to_external.h [new file with mode: 0644]
src_mobile/misc/widget_location.cpp [new file with mode: 0644]
src_mobile/misc/widget_location.h [new file with mode: 0644]
src_mobile/pkg-manager/CMakeLists.txt [new file with mode: 0755]
src_mobile/pkg-manager/DESCRIPTION [new file with mode: 0644]
src_mobile/pkg-manager/backendlib.cpp [new file with mode: 0644]
src_mobile/pkg-manager/pkgmgr_signal.cpp [new file with mode: 0644]
src_mobile/pkg-manager/pkgmgr_signal.h [new file with mode: 0644]
src_mobile/pkg-manager/pkgmgr_signal_dummy.h [new file with mode: 0644]
src_mobile/pkg-manager/pkgmgr_signal_interface.h [new file with mode: 0644]
src_mobile/wrt-installer/CMakeLists.txt [new file with mode: 0644]
src_mobile/wrt-installer/installer_callbacks_translate.cpp [new file with mode: 0644]
src_mobile/wrt-installer/installer_callbacks_translate.h [new file with mode: 0644]
src_mobile/wrt-installer/installer_main_thread.cpp [new file with mode: 0644]
src_mobile/wrt-installer/installer_main_thread.h [new file with mode: 0644]
src_mobile/wrt-installer/language_subtag_rst_tree.cpp [new file with mode: 0644]
src_mobile/wrt-installer/language_subtag_rst_tree.h [new file with mode: 0644]
src_mobile/wrt-installer/option_parser.cpp [new file with mode: 0644]
src_mobile/wrt-installer/option_parser.h [new file with mode: 0644]
src_mobile/wrt-installer/plugin_utils.cpp [new file with mode: 0644]
src_mobile/wrt-installer/plugin_utils.h [new file with mode: 0644]
src_mobile/wrt-installer/wrt-installer.cpp [new file with mode: 0644]
src_mobile/wrt-installer/wrt-installer.h [new file with mode: 0644]
src_mobile/wrt-installer/wrt_installer_api.cpp [new file with mode: 0644]
src_mobile/wrt-installer/wrt_installer_api.h [new file with mode: 0644]
src_mobile/wrt-installer/wrt_type.h [new file with mode: 0644]
src_wearable/CMakeLists.txt [new file with mode: 0755]
src_wearable/DESCRIPTION [new file with mode: 0644]
src_wearable/commons/installer_log.h [new file with mode: 0755]
src_wearable/commons/wrt_common_types.h [new file with mode: 0644]
src_wearable/commons/wrt_error.h [new file with mode: 0644]
src_wearable/commons/wrt_install_mode.h [new file with mode: 0644]
src_wearable/configuration_parser/deny_all_parser.cpp [new file with mode: 0644]
src_wearable/configuration_parser/deny_all_parser.h [new file with mode: 0644]
src_wearable/configuration_parser/element_parser.h [new file with mode: 0644]
src_wearable/configuration_parser/ignoring_parser.cpp [new file with mode: 0644]
src_wearable/configuration_parser/ignoring_parser.h [new file with mode: 0644]
src_wearable/configuration_parser/libiriwrapper.cpp [new file with mode: 0644]
src_wearable/configuration_parser/libiriwrapper.h [new file with mode: 0644]
src_wearable/configuration_parser/parser_runner.cpp [new file with mode: 0644]
src_wearable/configuration_parser/parser_runner.h [new file with mode: 0644]
src_wearable/configuration_parser/root_parser.h [new file with mode: 0755]
src_wearable/configuration_parser/widget_parser.cpp [new file with mode: 0755]
src_wearable/configuration_parser/widget_parser.h [new file with mode: 0755]
src_wearable/jobs/job.cpp [new file with mode: 0644]
src_wearable/jobs/job.h [new file with mode: 0644]
src_wearable/jobs/job_base.h [new file with mode: 0644]
src_wearable/jobs/job_exception_base.h [new file with mode: 0644]
src_wearable/jobs/job_exception_error.h [new file with mode: 0644]
src_wearable/jobs/job_types.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/job_plugin_install.cpp [new file with mode: 0755]
src_wearable/jobs/plugin_install/job_plugin_install.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_install_task.cpp [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_install_task.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_installer_context.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_installer_errors.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_installer_struct.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_metafile_reader.cpp [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_metafile_reader.h [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_objects.cpp [new file with mode: 0644]
src_wearable/jobs/plugin_install/plugin_objects.h [new file with mode: 0644]
src_wearable/jobs/widget_install/ace_registration.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/ace_registration.h [new file with mode: 0644]
src_wearable/jobs/widget_install/directory_api.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/directory_api.h [new file with mode: 0644]
src_wearable/jobs/widget_install/job_widget_install.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/job_widget_install.h [new file with mode: 0644]
src_wearable/jobs/widget_install/languages.def [new file with mode: 0644]
src_wearable/jobs/widget_install/manifest.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/manifest.h [new file with mode: 0755]
src_wearable/jobs/widget_install/task_ace_check.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_ace_check.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_certify.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_certify.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_certify_level.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_certify_level.h [new file with mode: 0755]
src_wearable/jobs/widget_install/task_commons.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_commons.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_configuration.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_configuration.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_database.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_database.h [new file with mode: 0755]
src_wearable/jobs/widget_install/task_encrypt_resource.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_encrypt_resource.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_file_manipulation.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_file_manipulation.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_install_ospsvc.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_install_ospsvc.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_manifest_file.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_manifest_file.h [new file with mode: 0755]
src_wearable/jobs/widget_install/task_pkg_info_update.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_pkg_info_update.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_prepare_files.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_prepare_files.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_prepare_reinstall.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_prepare_reinstall.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_process_config.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_process_config.h [new file with mode: 0755]
src_wearable/jobs/widget_install/task_recovery.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_recovery.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_remove_backup.cpp [new file with mode: 0755]
src_wearable/jobs/widget_install/task_remove_backup.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_smack.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_smack.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_status_check.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_status_check.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_update_files.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_update_files.h [new file with mode: 0644]
src_wearable/jobs/widget_install/task_user_data_manipulation.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/task_user_data_manipulation.h [new file with mode: 0644]
src_wearable/jobs/widget_install/view_mode.h [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_install_context.h [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_install_errors.h [new file with mode: 0755]
src_wearable/jobs/widget_install/widget_installer_struct.h [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_security.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_security.h [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_unzip.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_unzip.h [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_update_info.cpp [new file with mode: 0644]
src_wearable/jobs/widget_install/widget_update_info.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/job_widget_uninstall.cpp [new file with mode: 0755]
src_wearable/jobs/widget_uninstall/job_widget_uninstall.h [new file with mode: 0755]
src_wearable/jobs/widget_uninstall/task_check.cpp [new file with mode: 0755]
src_wearable/jobs/widget_uninstall/task_check.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_db_update.cpp [new file with mode: 0755]
src_wearable/jobs/widget_uninstall/task_db_update.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_delete_pkginfo.cpp [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_delete_pkginfo.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_remove_custom_handlers.cpp [new file with mode: 0755]
src_wearable/jobs/widget_uninstall/task_remove_custom_handlers.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_remove_files.cpp [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_remove_files.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_smack.cpp [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_smack.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_uninstall_ospsvc.cpp [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/task_uninstall_ospsvc.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/uninstaller_context.h [new file with mode: 0755]
src_wearable/jobs/widget_uninstall/widget_uninstall_errors.h [new file with mode: 0644]
src_wearable/jobs/widget_uninstall/widget_uninstaller_struct.h [new file with mode: 0644]
src_wearable/logic/installer_controller.cpp [new file with mode: 0644]
src_wearable/logic/installer_controller.h [new file with mode: 0644]
src_wearable/logic/installer_logic.cpp [new file with mode: 0755]
src_wearable/logic/installer_logic.h [new file with mode: 0755]
src_wearable/misc/feature_logic.cpp [new file with mode: 0755]
src_wearable/misc/feature_logic.h [new file with mode: 0644]
src_wearable/misc/libxml_utils.cpp [new file with mode: 0644]
src_wearable/misc/libxml_utils.h [new file with mode: 0644]
src_wearable/misc/plugin_path.cpp [new file with mode: 0644]
src_wearable/misc/plugin_path.h [new file with mode: 0644]
src_wearable/misc/wac_widget_id.cpp [new file with mode: 0644]
src_wearable/misc/wac_widget_id.h [new file with mode: 0644]
src_wearable/misc/widget_install_to_external.cpp [new file with mode: 0644]
src_wearable/misc/widget_install_to_external.h [new file with mode: 0644]
src_wearable/misc/widget_location.cpp [new file with mode: 0755]
src_wearable/misc/widget_location.h [new file with mode: 0755]
src_wearable/pkg-manager/CMakeLists.txt [new file with mode: 0755]
src_wearable/pkg-manager/DESCRIPTION [new file with mode: 0644]
src_wearable/pkg-manager/backendlib.cpp [new file with mode: 0644]
src_wearable/pkg-manager/pkgmgr_signal.cpp [new file with mode: 0644]
src_wearable/pkg-manager/pkgmgr_signal.h [new file with mode: 0644]
src_wearable/pkg-manager/pkgmgr_signal_dummy.h [new file with mode: 0644]
src_wearable/pkg-manager/pkgmgr_signal_interface.h [new file with mode: 0644]
src_wearable/wrt-installer/CMakeLists.txt [new file with mode: 0644]
src_wearable/wrt-installer/command_parser.cpp [new file with mode: 0644]
src_wearable/wrt-installer/command_parser.h [new file with mode: 0755]
src_wearable/wrt-installer/installer_callbacks_translate.cpp [new file with mode: 0644]
src_wearable/wrt-installer/installer_callbacks_translate.h [new file with mode: 0644]
src_wearable/wrt-installer/installer_main_thread.cpp [new file with mode: 0644]
src_wearable/wrt-installer/installer_main_thread.h [new file with mode: 0644]
src_wearable/wrt-installer/language_subtag_rst_tree.cpp [new file with mode: 0644]
src_wearable/wrt-installer/language_subtag_rst_tree.h [new file with mode: 0644]
src_wearable/wrt-installer/plugin_utils.cpp [new file with mode: 0644]
src_wearable/wrt-installer/plugin_utils.h [new file with mode: 0644]
src_wearable/wrt-installer/wrt-installer.cpp [new file with mode: 0755]
src_wearable/wrt-installer/wrt-installer.h [new file with mode: 0755]
src_wearable/wrt-installer/wrt_type.h [new file with mode: 0644]
tests/CMakeLists.txt [new file with mode: 0644]
tests/general/AceRegistrationTests.cpp [new file with mode: 0644]
tests/general/BackgroundPageTests.cpp [new file with mode: 0644]
tests/general/CMakeLists.txt [new file with mode: 0644]
tests/general/InstallerWrapper.cpp [new file with mode: 0644]
tests/general/InstallerWrapper.h [new file with mode: 0644]
tests/general/LanguageSubtagRstTreeTests.cpp [new file with mode: 0644]
tests/general/ManifestFile.cpp [new file with mode: 0644]
tests/general/ManifestFile.h [new file with mode: 0644]
tests/general/ManifestTests.cpp [new file with mode: 0644]
tests/general/NPluginsInstallTests.cpp [new file with mode: 0644]
tests/general/ParserRunnerTests.cpp [new file with mode: 0644]
tests/general/ParsingAccountTests.cpp [new file with mode: 0644]
tests/general/ParsingAllowNavigationTests.cpp [new file with mode: 0644]
tests/general/ParsingAppWidgetTests.cpp [new file with mode: 0644]
tests/general/ParsingCategoryTests.cpp [new file with mode: 0644]
tests/general/ParsingContentTests.cpp [new file with mode: 0644]
tests/general/ParsingCspTests.cpp [new file with mode: 0644]
tests/general/ParsingMetadataTests.cpp [new file with mode: 0644]
tests/general/ParsingSplashImgTests.cpp [new file with mode: 0644]
tests/general/ParsingTizenAppcontrolTests.cpp [new file with mode: 0644]
tests/general/ParsingTizenPrivilegeTests.cpp [new file with mode: 0644]
tests/general/PluginsInstallation.cpp [new file with mode: 0644]
tests/general/TaskConfigurationTests.cpp [new file with mode: 0644]
tests/general/TestInit.cpp [new file with mode: 0644]
tests/general/WidgetInstallManifestTests.cpp [new file with mode: 0644]
tests/general/WidgetLocationTests.cpp [new file with mode: 0644]
tests/general/WidgetUpdateTests.cpp [new file with mode: 0644]
tests/general/configs/AllowNavigationEmpty.xml [new file with mode: 0644]
tests/general/configs/AllowNavigationMultipleHosts.xml [new file with mode: 0644]
tests/general/configs/AllowNavigationMultipleHostsMultiline.xml [new file with mode: 0644]
tests/general/configs/AppWidgetAutoLaunchEmpty.xml [new file with mode: 0644]
tests/general/configs/AppWidgetAutoLaunchWrongValue.xml [new file with mode: 0644]
tests/general/configs/AppWidgetFull.xml [new file with mode: 0644]
tests/general/configs/AppWidgetIdEmpty.xml [new file with mode: 0644]
tests/general/configs/AppWidgetIdTooLong.xml [new file with mode: 0644]
tests/general/configs/AppWidgetIdTooShort.xml [new file with mode: 0644]
tests/general/configs/AppWidgetIdWrongChar.xml [new file with mode: 0644]
tests/general/configs/AppWidgetMinimal.xml [new file with mode: 0644]
tests/general/configs/AppWidgetMultipleBoxContent.xml [new file with mode: 0644]
tests/general/configs/AppWidgetMultipleBoxIcon.xml [new file with mode: 0644]
tests/general/configs/AppWidgetMultipleBoxLabel.xml [new file with mode: 0644]
tests/general/configs/AppWidgetMultiplePrimary.xml [new file with mode: 0644]
tests/general/configs/AppWidgetNoBoxContent.xml [new file with mode: 0644]
tests/general/configs/AppWidgetNoBoxLabel.xml [new file with mode: 0644]
tests/general/configs/AppWidgetNoId.xml [new file with mode: 0644]
tests/general/configs/AppWidgetNoPrimary.xml [new file with mode: 0644]
tests/general/configs/AppWidgetPrimaryEmpty.xml [new file with mode: 0644]
tests/general/configs/AppWidgetPrimaryWrongValue.xml [new file with mode: 0644]
tests/general/configs/AppWidgetUpdatePeriodEmpty.xml [new file with mode: 0644]
tests/general/configs/AppWidgetUpdatePeriodLow.xml [new file with mode: 0644]
tests/general/configs/AppWidgetUpdatePeriodWrongFormat.xml [new file with mode: 0644]
tests/general/configs/BoxContentEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxContentMouseEventEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxContentMouseEventWrongValue.xml [new file with mode: 0644]
tests/general/configs/BoxContentMultipleBoxSize.xml [new file with mode: 0644]
tests/general/configs/BoxContentMultiplePd.xml [new file with mode: 0644]
tests/general/configs/BoxContentNoMouseEvent.xml [new file with mode: 0644]
tests/general/configs/BoxContentNoSrc.xml [new file with mode: 0644]
tests/general/configs/BoxContentNoTouchEfect.xml [new file with mode: 0644]
tests/general/configs/BoxContentSrcEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxContentTouchEfectEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxContentTouchEfectWrongValue.xml [new file with mode: 0644]
tests/general/configs/BoxIconEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxIconSrcEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxLabelEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxSizeEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxSizeNoUserDecoration.xml [new file with mode: 0644]
tests/general/configs/BoxSizePreviewEmpty.xml [new file with mode: 0644]
tests/general/configs/BoxSizeUserDecorationEmpty.xml [new file with mode: 0644]
tests/general/configs/ContentEmpty.xml [new file with mode: 0644]
tests/general/configs/ContentSrcCorrect.xml [new file with mode: 0644]
tests/general/configs/ContentSrcEmpty.xml [new file with mode: 0644]
tests/general/configs/CspEmpty.xml [new file with mode: 0644]
tests/general/configs/CspReportOnlyEmpty.xml [new file with mode: 0644]
tests/general/configs/InstallConfig.xml [new file with mode: 0644]
tests/general/configs/MetadataDuplicatedKey.xml [new file with mode: 0644]
tests/general/configs/MetadataEmpty.xml [new file with mode: 0644]
tests/general/configs/MultipleAllowNavigation.xml [new file with mode: 0644]
tests/general/configs/MultipleContentCorrect.xml [new file with mode: 0644]
tests/general/configs/MultipleContentIncorrect.xml [new file with mode: 0644]
tests/general/configs/MultipleCsp.xml [new file with mode: 0644]
tests/general/configs/MultipleCspReportOnly.xml [new file with mode: 0644]
tests/general/configs/MultipleMetadata.xml [new file with mode: 0644]
tests/general/configs/NoAllowNavigation.xml [new file with mode: 0644]
tests/general/configs/NoContent.xml [new file with mode: 0644]
tests/general/configs/NoCsp.xml [new file with mode: 0644]
tests/general/configs/NoMetadata.xml [new file with mode: 0644]
tests/general/configs/PdHeightEmpty.xml [new file with mode: 0644]
tests/general/configs/PdHeightExcessive.xml [new file with mode: 0644]
tests/general/configs/PdHeightTooLow.xml [new file with mode: 0644]
tests/general/configs/PdHeightWrongValue.xml [new file with mode: 0644]
tests/general/configs/PdNoHeight.xml [new file with mode: 0644]
tests/general/configs/PdNoSrc.xml [new file with mode: 0644]
tests/general/configs/PdNoWidth.xml [new file with mode: 0644]
tests/general/configs/PdSrcEmpty.xml [new file with mode: 0644]
tests/general/configs/PdWidthEmpty.xml [new file with mode: 0644]
tests/general/configs/PdWidthNegative.xml [new file with mode: 0644]
tests/general/configs/PdWidthWrongValue.xml [new file with mode: 0644]
tests/general/configs/PdWidthZero.xml [new file with mode: 0644]
tests/general/configs/config_category1.xml [new file with mode: 0644]
tests/general/configs/config_category2.xml [new file with mode: 0644]
tests/general/configs/config_category3.xml [new file with mode: 0644]
tests/general/configs/config_category4.xml [new file with mode: 0644]
tests/general/configs/config_privilege1.xml [new file with mode: 0644]
tests/general/configs/config_privilege2.xml [new file with mode: 0644]
tests/general/configs/config_privilege3.xml [new file with mode: 0644]
tests/general/configs/config_privilege4.xml [new file with mode: 0644]
tests/general/configs/config_privilege5.xml [new file with mode: 0644]
tests/general/configs/config_privilege6.xml [new file with mode: 0644]
tests/general/configs/config_splash1.xml [new file with mode: 0644]
tests/general/configs/config_splash2.xml [new file with mode: 0644]
tests/general/configs/config_splash3.xml [new file with mode: 0644]
tests/general/configs/config_splash4.xml [new file with mode: 0644]
tests/general/widgets/account.wgt [new file with mode: 0644]
tests/general/widgets/allowNavigation.wgt [new file with mode: 0644]
tests/general/widgets/app-control.wgt [new file with mode: 0644]
tests/general/widgets/appWidgetFull.wgt [new file with mode: 0644]
tests/general/widgets/appWidgetIncorrect.wgt [new file with mode: 0644]
tests/general/widgets/appWidgetMinimal.wgt [new file with mode: 0644]
tests/general/widgets/bg-00-with_bg.wgt [new file with mode: 0644]
tests/general/widgets/bg-01-missing_file.wgt [new file with mode: 0644]
tests/general/widgets/bg-02-without_bg.wgt [new file with mode: 0644]
tests/general/widgets/category.wgt [new file with mode: 0644]
tests/general/widgets/contentCorrect.wgt [new file with mode: 0644]
tests/general/widgets/contentIncorrect.wgt [new file with mode: 0644]
tests/general/widgets/csp.wgt [new file with mode: 0644]
tests/general/widgets/inst_nplug_1.wgt [new file with mode: 0644]
tests/general/widgets/inst_nplug_2.wgt [new file with mode: 0644]
tests/general/widgets/inst_nplug_3.wgt [new file with mode: 0644]
tests/general/widgets/inst_nplug_4.wgt [new file with mode: 0644]
tests/general/widgets/manifest.wgt [new file with mode: 0644]
tests/general/widgets/metadata.wgt [new file with mode: 0644]
tests/general/widgets/privilege.wgt [new file with mode: 0644]
tests/general/widgets/splash.wgt [new file with mode: 0644]
tests/general/widgets/widgetFakeConfig.wgt [new file with mode: 0644]
tests/general/widgets/widgetInDir.tar [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer100Signed.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer100Unsigned.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220Signed.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220Unsigned.wgt [new file with mode: 0644]
tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt [new file with mode: 0644]
uncrustify.cfg [new file with mode: 0644]
uncrustify.sh [new file with mode: 0755]
wrt-installer.manifest [new file with mode: 0644]
wrt-installer.rule [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..350168c
--- /dev/null
@@ -0,0 +1,139 @@
+# 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)
+PROJECT("wrt-installer")
+
+############################# cmake packages ##################################
+
+INCLUDE(FindPkgConfig)
+
+############################# build type ######################################
+
+IF(NOT CMAKE_BUILD_TYPE)
+    SET(CMAKE_BUILD_TYPE "Release")
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+############################# compilation defines #############################
+
+OPTION(DPL_LOG "DPL logs status" ON)
+OPTION(WITH_TESTS "Build tests" OFF)
+OPTION(MULTIPROCESS_SERVICE_SUPPORT "Process per service" OFF)
+OPTION(MULTIPROCESS_SERVICE_SUPPORT_INLINE "Process per service - inline mode support" OFF)
+OPTION(SCHEMA_VALIDATION_SUPPORT "Support for XML schema validation" OFF)
+OPTION(NFC_APP_CONTROL_EXCEPTION "Enable exception handling for NFC app-control" ON)
+
+SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build")
+INCLUDE(Options)
+
+############################# compiler flags ##################################
+
+SET(CMAKE_C_FLAGS_PROFILING    "-O2")
+SET(CMAKE_CXX_FLAGS_PROFILING  "-O2 -std=c++0x")
+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 -fvisibility-inlines-hidden")
+SET(CMAKE_CXX_FLAGS_CCOV       "-O0 -std=c++0x -g --coverage")
+
+IF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling")
+    MESSAGE(STATUS "Logging enabled for DPL")
+    ADD_DEFINITIONS("-DDPL_LOGS_ENABLED")
+ELSE(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling")
+    MESSAGE(STATUS "Logging disabled for DPL")
+ENDIF(DPL_LOG AND NOT CMAKE_BUILD_TYPE MATCHES "profiling")
+MESSAGE(STATUS "WITH_TESTS: " ${WITH_TESTS})
+IF(MULTIPROCESS_SERVICE_SUPPORT)
+    ADD_DEFINITIONS("-DMULTIPROCESS_SERVICE_SUPPORT")
+    IF (MULTIPROCESS_SERVICE_SUPPORT_INLINE)
+        ADD_DEFINITIONS("-DMULTIPROCESS_SERVICE_SUPPORT_INLINE")
+    ENDIF(MULTIPROCESS_SERVICE_SUPPORT_INLINE)
+ENDIF(MULTIPROCESS_SERVICE_SUPPORT)
+IF(SCHEMA_VALIDATION_SUPPORT)
+    MESSAGE(STATUS "XML Schema validation of installed app enabled")
+    ADD_DEFINITIONS("-DSCHEMA_VALIDATION_ENABLED")
+ENDIF(SCHEMA_VALIDATION_SUPPORT)
+IF(NFC_APP_CONTROL_EXCEPTION)
+    MESSAGE(STATUS "Exception handling for NFC app-control is enabled")
+    ADD_DEFINITIONS("-DNFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY")
+ENDIF(NFC_APP_CONTROL_EXCEPTION)
+
+IF(DEVICE_PROFILE STREQUAL "wearable")
+    MESSAGE(STATUS "Device Profile: wearable")
+    ADD_DEFINITIONS("-DDEVICE_PROFILE_WEARABLE")
+ELSE(DEVICE_PROFILE STREQUAL "wearable")
+    MESSAGE(STATUS "Device Profile: mobile")
+    ADD_DEFINITIONS("-DDEVICE_PROFILE_MOBILE")
+       ADD_DEFINITIONS("-DWRT_SMACK_ENABLED")  # enable smack
+
+       OPTION(CSP_SUPPORT "Support for csp policy" ON)
+       OPTION(ALLOW_NAVIGATION_SUPPORT "Support for allow-navigation" ON)
+
+       IF(CSP_SUPPORT)
+               ADD_DEFINITIONS("-DCSP_ENABLED")
+       ENDIF(CSP_SUPPORT)
+       IF(ALLOW_NAVIGATION_SUPPORT)
+               ADD_DEFINITIONS("-DALLOW_NAVIGATION_ENABLED")
+       ENDIF(ALLOW_NAVIGATION_SUPPORT)
+ENDIF(DEVICE_PROFILE STREQUAL "wearable")
+
+# 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")
+
+# 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")           # accept C++11x standard
+ADD_DEFINITIONS("-DWRT_INSTALLER_LOG")  # enable installer log
+ADD_DEFINITIONS("-DDBOX_ENABLED")      # enable dynamic box features
+ADD_DEFINITIONS("-DIME_ENABLED")        # enable Ime features
+ADD_DEFINITIONS("-DSERVICE_ENABLED")    # enable Service features
+
+############################# Targets names ###################################
+
+SET(TARGET_INSTALLER_STATIC "wrt-installer_static")
+SET(TARGET_INSTALLER "wrt-installer")
+SET(TARGET_BACKEND_LIB "wgt")
+
+############################# subdirectories ##################################
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(configuration)
+
+IF(WITH_TESTS)
+    ADD_SUBDIRECTORY(tests)
+ENDIF(WITH_TESTS)
+
+########################## smack rule install #################################
+INSTALL(FILES   ${CMAKE_SOURCE_DIR}/wrt-installer.rule
+    DESTINATION /etc/smack/accesses2.d/
+)
+
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..247c97d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,203 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/build/Options.cmake b/build/Options.cmake
new file mode 100644 (file)
index 0000000..05087e0
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (c) 2013 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        Options.cmake
+# @author      Tae-Jeong Lee (taejeong.lee@samsung.com)
+#
+
+# Macro declaration
+#  - WRT_OPTION() : Wrapper omitting description argument from OPTION() command.
+MACRO(WRT_OPTION feature_name on_off)
+    OPTION(${feature_name} "" ${on_off})
+ENDMACRO(WRT_OPTION)
+
+# Use Feature
+#   Use a particular optional platform service or third-party library
+#
+# Description : <text>
+#               <text>
+# Author : <text>(<email>) - <date>
+# WRT_OPTION(<REPOSITORY_NAME>_USE_<FEATURE_NAME> ON/OFF)
+
+
+# Enable Feature
+#   Turn on a specific feature of WRT
+#
+# Description : <text>
+#               <text>
+# Author : <text>(<email>) - <date>
+# WRT_OPTION(<REPOSITORY_NAME>_ENABLE_<FEATURE_NAME> ON/OFF)
+
diff --git a/configuration/CMakeLists.txt b/configuration/CMakeLists.txt
new file mode 100644 (file)
index 0000000..380f512
--- /dev/null
@@ -0,0 +1,2 @@
+FILE(GLOB XSD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.xsd")
+INSTALL(FILES ${XSD_FILES} DESTINATION /usr/etc/wrt-installer/)
diff --git a/configuration/access.xsd b/configuration/access.xsd
new file mode 100644 (file)
index 0000000..f2404e4
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.w3.org/ns/widgets" xmlns:widgets="http://www.w3.org/ns/widgets">
+  <xs:include schemaLocation="common.xsd"/>
+  <!--
+    Widget Access Request Policy <http://www.w3.org/TR/widgets-access/>
+    requires common.rnc
+  -->
+  <xs:element name="access">
+    <xs:complexType mixed="true">
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:foreignAttribute"/>
+      <xs:attribute name="origin" type="xs:string"/>
+      <!-- w3c policy testcases
+      <xs:attribute name="origin" use="required">
+        <xs:simpleType>
+          <xs:union memberTypes="xs:anyURI">
+            <xs:simpleType>
+              <xs:restriction base="xs:string">
+                <xs:enumeration value="*"/>
+              </xs:restriction>
+            </xs:simpleType>
+          </xs:union>
+        </xs:simpleType>
+      </xs:attribute>
+      -->
+      <xs:attribute name="subdomains" type="widgets:data.boolean"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/configuration/common.xsd b/configuration/common.xsd
new file mode 100644 (file)
index 0000000..2b9a0d2
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:widgets="http://www.w3.org/ns/widgets">
+  <xs:include schemaLocation="local.xsd"/>
+
+  <xs:group name="extension">
+    <xs:sequence>
+      <xs:group ref="anyElement"/>
+    </xs:sequence>
+  </xs:group>
+
+  <xs:attributeGroup name="extension">
+    <xs:attributeGroup ref="anyAttribute"/>
+  </xs:attributeGroup>
+
+  <xs:group name="foreignElement">
+    <xs:sequence>
+      <xs:choice minOccurs="0">
+        <xs:group ref="local"/>
+      </xs:choice>
+    </xs:sequence>
+  </xs:group>
+
+  <xs:attributeGroup name="foreignAttribute">
+    <xs:anyAttribute namespace="##other" processContents="skip"/>
+  </xs:attributeGroup>
+
+  <xs:group name="anyElement">
+    <xs:sequence>
+      <xs:any processContents="skip"/>
+    </xs:sequence>
+  </xs:group>
+
+  <xs:attributeGroup name="anyAttribute">
+    <xs:anyAttribute processContents="skip"/>
+  </xs:attributeGroup>
+
+  <xs:simpleType name="data.positiveNumber">
+    <xs:restriction base="xs:string">
+      <!-- W3C testcase <xs:pattern value="[1-9]\d*"/> -->
+      <xs:pattern value="\s*([1-9]\d*)?.*"/> <!-- accept everything anyway -->
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:simpleType name="data.boolean">
+    <xs:restriction base="xs:string">
+      <!-- w3c testcases - ignore invalid
+      <xs:enumeration value="true"/>
+      <xs:enumeration value="false"/>
+      -->
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:attributeGroup name="global.attrs">
+    <xs:attribute name="dir">
+      <xs:simpleType>
+        <xs:list>
+          <xs:simpleType>
+            <xs:restriction base="xs:token">
+              <xs:enumeration value="ltr"/>
+              <xs:enumeration value="rtl"/>
+              <xs:enumeration value="lro"/>
+              <xs:enumeration value="rlo"/>
+            </xs:restriction>
+          </xs:simpleType>
+        </xs:list>
+      </xs:simpleType>
+    </xs:attribute>
+  </xs:attributeGroup>
+
+  <xs:attributeGroup name="global.xml">
+    <xs:anyAttribute namespace="##other" processContents="skip"/>
+  </xs:attributeGroup>
+
+  <xs:simpleType name="data.versionNumber">
+    <xs:restriction base="xs:string">
+      <xs:pattern value="[0-9]{1,3}\.[0-9]{1,3}(\.[0-9]{1,5})?"/>
+    </xs:restriction>
+  </xs:simpleType>
+</xs:schema>
diff --git a/configuration/config.xml b/configuration/config.xml
new file mode 100755 (executable)
index 0000000..492e3df
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" version="00.00.0001" viewmodes="fullscreen windowed floating">
+  <name>hello</name>
+  <name xml:lang="en">hello</name>
+  <icon src="icon.png" />
+
+  <!-- tizen application element -->
+  <tizen:application id="GfeI4eyhBG.1" package="GfeI4eyhBG" required_version="2.1"/>
+
+  <!-- tizen setting element -->
+  <!-- unecessary for tizenw
+  <tizen:setting screen-orientation="landscape" context-menu="disable"/>
+  -->
+  <tizen:setting background-support="disable" encryption="disable" hwkey-event="enable"/>
+
+  <!-- tizen app-control element -->
+  <tizen:app-control>
+    <tizen:src name="index.html"/>
+    <tizen:operation name="http://tizen.org/appcontrol/operation/default"/>
+    <tizen:uri name="http"/>
+    <tizen:mime name="html"/>
+  </tizen:app-control>
+
+  <!-- IME_ENABLED -->
+  <tizen:ime>
+    <tizen:uuid>6135122a-a428-40d2-8feb-a75f462c202c</tizen:uuid>
+    <tizen:languages>
+      <tizen:language>en-us</tizen:language>
+      <tizen:language>ko-kr</tizen:language>
+    </tizen:languages>
+  </tizen:ime>
+
+  <!-- SERVICE_ENABLED -->
+  <tizen:service id="GfeI4eyhBG.1.service" auto_restart="true" on_boot="true">
+    <tizen:service-content src="service.js"/>
+    <tizen:service-name>WebService</tizen:service-name>
+    <tizen:service-icon src="service.png"/>
+    <tizen:service-description>WebService</tizen:service-description>
+  </tizen:service>
+
+  <!-- tizen content-security-policy element -->
+  <tizen:content-security-policy>"img-src http://test.com 'unsafe-inline'; script-src 'unsafe-inline';"</tizen:content-security-policy>
+  <!-- unecessary for tizenw
+  <tizen:content-security-policy-report-only>img-src http://test.com 'unsafe-inline'; script-src 'unsafe-inline';</tizen:content-security-policy-report-only>
+  -->
+
+  <!-- tizen allow-navigation element -->
+  <!-- unecessary for tizenw
+  <tizen:allow-navigation>test.com</tizen:allow-navigation>
+  -->
+
+  <!-- tizen metadata -->
+  <tizen:metadata key="key_1" value="value_1"/>
+  <tizen:metadata key="key_2"/>
+
+  <!-- unecessary for tizenw
+  <tizen:app-widget id="jNZe0gZhHG.Dynmic.default" primary="true">
+    <tizen:box-label xml:lang="en">WEB DYNAMICBOX</tizen:box-label>
+    <tizen:box-label xml:lang="ef">WEB DYNAMICBOX</tizen:box-label>
+    <tizen:box-label xml:lang="tc">WEB DYNAMICBOX</tizen:box-label>
+    <tizen:box-icon src="icon.png"/>
+    <tizen:box-content src="box/index.html">
+      <tizen:box-size>1x1</tizen:box-size>
+      <tizen:box-size>2x1</tizen:box-size>
+      <tizen:box-size>2x2</tizen:box-size>
+      <tizen:pd src="pd/index.html" width="720" height="200"/>
+   </tizen:box-content>
+ </tizen:app-widget>
+ -->
+
+  <!-- splash screen -->
+  <!-- unecessary for tizenw
+  <tizen:splash src="splash.jpg" />
+  -->
+
+  <!-- category -->
+  <tizen:category name="com.samsung.wmanager.WATCH_CLOCK"/>
+</widget>
diff --git a/configuration/feature-wrt.properties b/configuration/feature-wrt.properties
new file mode 100644 (file)
index 0000000..5b7fb11
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+    <entry key="http://tizen.org/feature/network.push"/>
+    <entry key="http://tizen.org/feature/network.bluetooth"/>
+    <entry key="http://tizen.org/feature/network.telephony"/>
+    <entry key="http://tizen.org/feature/network.telephony.mms"/>
+    <entry key="http://tizen.org/feature/network.nfc"/>
+    <entry key="http://tizen.org/feature/network.secure_element"/>
+    <entry key="http://tizen.org/feature/network.wifi"/>
+
+    <entry key="http://tizen.org/feature/camera"/>
+    <entry key="http://tizen.org/feature/microphone"/>
+    <entry key="http://tizen.org/feature/location.gps"/>
+    <entry key="http://tizen.org/feature/sensor.accelerometer"/>
+    <entry key="http://tizen.org/feature/sensor.gyroscope"/>
+    <entry key="http://tizen.org/feature/sensor.magnetometer"/>
+
+    <entry key="http://tizen.org/feature/screen.size.all"/>
+    <entry key="http://tizen.org/feature/screen.size.normal"/>
+    <entry key="http://tizen.org/feature/screen.size.normal.320.480"/>
+    <entry key="http://tizen.org/feature/screen.size.normal.480.800"/>
+    <entry key="http://tizen.org/feature/screen.size.normal.540.960"/>
+    <entry key="http://tizen.org/feature/screen.size.normal.600.1024"/>
+    <entry key="http://tizen.org/feature/screen.size.normal.720.1280"/>
+    <entry key="http://tizen.org/feature/screen.size.normal.1080.1920"/>
+</properties>
diff --git a/configuration/local.xsd b/configuration/local.xsd
new file mode 100644 (file)
index 0000000..4aecb7d
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:widgets="http://www.w3.org/ns/widgets">
+    <xs:group name="local">
+        <xs:sequence>
+            <xs:any namespace="##other" processContents="skip"/>
+        </xs:sequence>
+    </xs:group>
+</xs:schema>
diff --git a/configuration/packaging-configuration.xsd b/configuration/packaging-configuration.xsd
new file mode 100755 (executable)
index 0000000..0990be2
--- /dev/null
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.w3.org/ns/widgets" xmlns:widgets="http://www.w3.org/ns/widgets">
+  <xs:include schemaLocation="common.xsd"/>
+  <xs:include schemaLocation="access.xsd"/>
+  <xs:include schemaLocation="updates.xsd"/>
+  <xs:import namespace="http://tizen.org/ns/widgets" schemaLocation="widgets.tizen.xsd"/>
+  <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
+  <!--
+    Widget Packaging and Configuration <http://www.w3.org/TR/widgets/>
+    requires common.rnc
+  -->
+  <xs:element name="widget">
+    <xs:complexType>
+      <xs:complexContent>
+        <xs:extension base="widgets:group.widgetContent">
+          <xs:attributeGroup ref="widgets:global.attrs"/>
+          <xs:attributeGroup ref="widgets:global.xml"/>
+          <xs:attributeGroup ref="widgets:extension"/>
+          <xs:attribute name="id" type="xs:anyURI"/>
+          <xs:attribute name="defaultlocale"/>
+          <xs:attribute name="version" type="widgets:data.versionNumber"/>
+          <xs:attribute name="min-version" type="widgets:data.versionNumber"/>
+          <xs:attribute name="height" type="widgets:data.positiveNumber"/>
+          <xs:attribute name="width" type="widgets:data.positiveNumber"/>
+          <xs:attribute name="viewmodes">
+            <xs:simpleType>
+              <xs:list>
+                <xs:simpleType>
+                  <xs:restriction base="xs:token">
+                    <xs:enumeration value="windowed"/>
+                    <xs:enumeration value="floating"/>
+                    <xs:enumeration value="fullscreen"/>
+                    <xs:enumeration value="maximized"/>
+                    <xs:enumeration value="minimized"/>
+                  </xs:restriction>
+                </xs:simpleType>
+              </xs:list>
+            </xs:simpleType>
+          </xs:attribute>
+          <!-- Requirment from IDE UX -->
+          <xs:attribute ref="xml:lang"/>
+        </xs:extension>
+      </xs:complexContent>
+    </xs:complexType>
+  </xs:element>
+  <xs:complexType name="group.widgetContent" mixed="true">
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:choice>
+        <xs:element ref="widgets:name"/>
+        <xs:element ref="widgets:description"/>
+        <xs:element ref="widgets:icon"/>
+        <xs:element ref="widgets:author"/>
+        <xs:element ref="widgets:license"/>
+        <xs:element ref="widgets:content"/>
+        <xs:element ref="widgets:feature"/>
+        <xs:element ref="widgets:preference"/>
+
+        <xs:element ref="tizen:app-control"  maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <xs:element ref="tizen:setting"  maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+<!-- IME_ENABLED -->
+        <xs:element ref="tizen:ime" minOccurs="0" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+<!-- SERVICE_ENABLED -->
+        <xs:element ref="tizen:service" minOccurs="0" maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <xs:element ref="tizen:application" minOccurs="1" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+<!-- unecessary for tizenw
+        <xs:element ref="tizen:content"  minOccurs="1" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+-->
+        <xs:element ref="tizen:privilege"  minOccurs="0" maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <xs:element ref="tizen:content-security-policy" minOccurs="0" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <xs:element ref="tizen:content-security-policy-report-only" minOccurs="0" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <xs:element ref="tizen:allow-navigation" minOccurs="0" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <xs:element ref="tizen:app-widget"  minOccurs="0" maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+<!-- unecessary for tizenw
+        <xs:element ref="tizen:account"  minOccurs="0" maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+-->
+        <xs:element ref="tizen:metadata"  minOccurs="0" maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+<!-- unecessary for tizenw
+        <xs:element ref="tizen:splash"  minOccurs="0" maxOccurs="1" xmlns:tizen="http://tizen.org/ns/widgets"/>
+-->
+        <xs:element ref="tizen:category"  minOccurs="0" maxOccurs="unbounded" xmlns:tizen="http://tizen.org/ns/widgets"/>
+        <!-- W3C testcases fail - should accept any element -->
+        <!--  <xs:group minOccurs="0" maxOccurs="unbounded" ref="widgets:foreignElement"/> -->
+      </xs:choice>
+      <xs:element ref="widgets:access"/>
+      <!--   <xs:element ref="widgets:update-description"/> -->
+    </xs:choice>
+  </xs:complexType>
+  <xs:element name="name">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="widgets:span"/>
+        <xs:group ref="widgets:foreignElement"/>
+      </xs:choice>
+      <!-- Requirment from IDE UX -->
+      <xs:attribute ref="xml:lang"/>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+      <xs:attribute name="short"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="description">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="widgets:span"/>
+        <xs:group ref="widgets:foreignElement"/>
+      </xs:choice>
+      <!-- Requirment from IDE UX -->
+      <xs:attribute ref="xml:lang"/>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="icon">
+    <xs:complexType>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:foreignAttribute"/>
+      <!-- w3c testcase - must ignore
+      <xs:attribute name="src" use="required" type="xs:anyURI"/>
+      -->
+      <xs:attribute name="src" type="xs:anyURI"/>
+      <xs:attribute name="height" type="widgets:data.positiveNumber"/>
+      <xs:attribute name="width" type="widgets:data.positiveNumber"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="author">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="widgets:span"/>
+        <xs:group ref="widgets:foreignElement"/>
+        <!-- W3C testcases fail - should accept any element -->
+      </xs:choice>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+      <xs:attribute name="href" type="xs:anyURI"/>
+      <xs:attribute name="email" type="xs:string"/>
+      <!-- fails W3C testcases
+      <xs:attribute name="email">
+        <xs:simpleType>
+          <xs:restriction base="xs:string">
+            <xs:pattern value=".+@.+"/>
+          </xs:restriction>
+        </xs:simpleType>
+      </xs:attribute>
+       -->
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="license">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="widgets:span"/>
+        <xs:group ref="widgets:foreignElement"/>
+      </xs:choice>
+      <!-- Requirment from IDE UX -->
+      <xs:attribute ref="xml:lang"/>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+      <xs:attribute name="href" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="content">
+    <xs:complexType>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:foreignAttribute"/>
+      <!-- w3c testcase - ignore not valid
+      <xs:attribute name="src" use="required" type="xs:anyURI"/>
+      -->
+      <xs:attribute name="src" type="xs:string"/>
+      <xs:attribute name="type"/>
+      <xs:attribute name="encoding"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="feature">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="widgets:param"/>
+        <xs:group ref="widgets:foreignElement"/>
+      </xs:choice>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+      <!-- w3c tescase - must ignore
+      <xs:attribute name="name" use="required" type="xs:anyURI"/>
+      -->
+      <xs:attribute name="name" type="xs:anyURI"/>
+      <xs:attribute name="required" type="widgets:data.boolean"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="param">
+    <xs:complexType mixed="true">
+      <xs:group minOccurs="0" maxOccurs="unbounded" ref="widgets:foreignElement"/>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+      <xs:attribute name="name"/>
+      <xs:attribute name="value"/>
+      <!-- w3c testcase - must ignore
+      <xs:attribute name="name" use="required"/>
+      <xs:attribute name="value" use="required"/>
+      -->
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="span">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="widgets:span"/>
+        <xs:group ref="widgets:foreignElement"/>
+      </xs:choice>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="preference">
+    <xs:complexType mixed="true">
+      <xs:group minOccurs="0" maxOccurs="unbounded" ref="widgets:foreignElement"/>
+      <xs:attributeGroup ref="widgets:global.attrs"/>
+      <xs:attributeGroup ref="widgets:global.xml"/>
+      <xs:attributeGroup ref="widgets:extension"/>
+      <!-- w3c testcase -required but missing
+      <xs:attribute name="name" use="required"/>
+      -->
+      <xs:attribute name="name"/>
+      <xs:attribute name="value"/>
+      <xs:attribute name="readonly" type="widgets:data.boolean"/>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
diff --git a/configuration/privilege-wrt.properties b/configuration/privilege-wrt.properties
new file mode 100644 (file)
index 0000000..dc36b93
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">\r
+<properties>\r
+    <entry key="http://tizen.org/privilege/location"/>\r
+    <entry key="http://tizen.org/privilege/notification"/>\r
+    <entry key="http://tizen.org/privilege/mediacapture"/>\r
+    <entry key="http://tizen.org/privilege/fullscreen"/>\r
+    <entry key="http://tizen.org/privilege/unlimitedstorage"/>\r
+</properties>\r
diff --git a/configuration/signature_schema.xsd b/configuration/signature_schema.xsd
new file mode 100644 (file)
index 0000000..1ca3bd3
--- /dev/null
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.w3.org/2000/09/xmldsig#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
+  <!--
+    Relax NG Grammar for XML Signature
+    Namespace: http://www.w3.org/2000/09/xmldsig#
+    $Revision: 1.7 $ on $Date: 2008/07/16 18:04:37 $ by $Author: roessler $
+
+    Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+            of Technology, Institut National de Recherche en Informatique et en
+            Automatique, Keio University). All Rights Reserved.
+    http://www.w3.org/Consortium/Legal/
+
+    This document is governed by the W3C Software License [1] as described
+    in the FAQ [2].
+
+    [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+    [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+
+    Constructed by hand from xmldsig-core-schema.xsd by
+    Norman.Walsh@marklogic.com on 5 May 2008.
+
+    Notes:
+
+    You must not use the RELAX NG DTD Compatibility features with thi
+    grammar. DTD Compatibility features, ID type attributes, and
+    wildcard attributes are mutually exclusive.
+
+    The definition for the Signature element includes a SignatureType
+    pattern. The rest of the patterns are "inline". This is a matter of
+    style. I constructed only one "type" pattern as an example of the
+    style, not because it's significant in the Signature pattern.
+  -->
+  <!-- Start Signature -->
+  <xs:complexType name="SignatureType">
+    <xs:sequence>
+      <xs:element ref="ds:SignedInfo"/>
+      <xs:element ref="ds:SignatureValue"/>
+      <xs:element minOccurs="0" ref="ds:KeyInfo"/>
+      <xs:element maxOccurs="unbounded" ref="ds:Object"/>
+    </xs:sequence>
+    <xs:attribute name="Id" type="xs:ID"/>
+  </xs:complexType>
+  <xs:element name="Signature" type="ds:SignatureType"/>
+  <xs:element name="SignatureValue">
+    <xs:complexType>
+      <xs:simpleContent>
+        <xs:extension base="xs:base64Binary">
+          <xs:attribute name="Id" type="xs:ID"/>
+        </xs:extension>
+      </xs:simpleContent>
+    </xs:complexType>
+  </xs:element>
+  <!-- Start SignedInfo -->
+  <xs:element name="SignedInfo">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="ds:CanonicalizationMethod"/>
+        <xs:element ref="ds:SignatureMethod"/>
+        <xs:element maxOccurs="unbounded" ref="ds:Reference"/>
+      </xs:sequence>
+      <xs:attribute name="Id" type="xs:ID"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="CanonicalizationMethod">
+    <xs:complexType mixed="true">
+      <xs:group minOccurs="0" maxOccurs="unbounded" ref="ds:anyElement"/>
+      <xs:attribute name="Algorithm" use="required" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="SignatureMethod">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="ds:HMACOutputLength"/>
+        <xs:group ref="ds:anyOtherElement"/>
+      </xs:choice>
+      <xs:attribute name="Algorithm" use="required" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <!-- Start Reference -->
+  <xs:element name="Reference">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element minOccurs="0" ref="ds:Transforms"/>
+        <xs:element ref="ds:DigestMethod"/>
+        <xs:element ref="ds:DigestValue"/>
+      </xs:sequence>
+      <xs:attribute name="Id" type="xs:ID"/>
+      <xs:attribute name="URI" type="xs:anyURI"/>
+      <xs:attribute name="Type" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="Transforms">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element maxOccurs="unbounded" ref="ds:Transform"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="Transform">
+    <xs:complexType>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:group ref="ds:anyOtherElement"/>
+        <xs:element ref="ds:XPath"/>
+      </xs:choice>
+      <xs:attribute name="Algorithm" use="required" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="XPath" type="xs:string"/>
+  <!-- End Reference -->
+  <xs:element name="DigestMethod">
+    <xs:complexType>
+      <xs:group minOccurs="0" maxOccurs="unbounded" ref="ds:anyOtherElement"/>
+      <xs:attribute name="Algorithm" use="required" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="DigestValue" type="ds:DigestValueType"/>
+  <xs:simpleType name="DigestValueType">
+    <xs:restriction base="xs:base64Binary"/>
+  </xs:simpleType>
+  <!-- End SignedInfo -->
+  <!-- Start KeyInfo -->
+  <xs:element name="KeyInfo">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="ds:KeyName"/>
+        <xs:element ref="ds:KeyValue"/>
+        <xs:element ref="ds:RetrievalMethod"/>
+        <xs:element ref="ds:X509Data"/>
+        <xs:element ref="ds:PGPData"/>
+        <xs:element ref="ds:SPKIData"/>
+        <xs:element ref="ds:MgmtData"/>
+        <xs:group ref="ds:anyOtherElement"/>
+      </xs:choice>
+      <xs:attribute name="Id" type="xs:ID"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="KeyName" type="xs:string"/>
+  <xs:element name="MgmtData" type="xs:string"/>
+  <xs:element name="KeyValue">
+    <xs:complexType mixed="true">
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="ds:DSAKeyValue"/>
+        <xs:element ref="ds:RSAKeyValue"/>
+        <xs:group ref="ds:anyOtherElement"/>
+      </xs:choice>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="RetrievalMethod">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element minOccurs="0" ref="ds:Transforms"/>
+      </xs:sequence>
+      <xs:attribute name="URI" use="required" type="xs:anyURI"/>
+      <xs:attribute name="Type" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <!-- Start X509Data -->
+  <xs:element name="X509Data">
+    <xs:complexType>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="ds:X509IssuerSerial"/>
+        <xs:element ref="ds:X509SKI"/>
+        <xs:element ref="ds:X509SubjectName"/>
+        <xs:element ref="ds:X509Certificate"/>
+        <xs:element ref="ds:X509CRL"/>
+        <xs:group ref="ds:anyOtherElement"/>
+      </xs:choice>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="X509IssuerSerial">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="ds:X509IssuerName"/>
+        <xs:element ref="ds:X509SerialNumber"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="X509IssuerName" type="xs:string"/>
+  <xs:element name="X509SerialNumber" type="xs:integer"/>
+  <xs:element name="X509SKI" type="xs:base64Binary"/>
+  <xs:element name="X509SubjectName" type="xs:string"/>
+  <xs:element name="X509Certificate" type="xs:base64Binary"/>
+  <xs:element name="X509CRL" type="xs:base64Binary"/>
+  <!-- End X509Data -->
+  <!-- Begin PGPData -->
+  <xs:element name="PGPData">
+    <xs:complexType>
+      <xs:choice>
+        <xs:sequence>
+          <xs:element ref="ds:PGPKeyID"/>
+          <xs:element minOccurs="0" ref="ds:PGPKeyPacket"/>
+          <xs:group minOccurs="0" maxOccurs="unbounded" ref="ds:anyOtherElement"/>
+        </xs:sequence>
+        <xs:sequence>
+          <xs:element ref="ds:PGPKeyPacket"/>
+          <xs:group minOccurs="0" maxOccurs="unbounded" ref="ds:anyOtherElement"/>
+        </xs:sequence>
+      </xs:choice>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="PGPKeyID" type="xs:base64Binary"/>
+  <xs:element name="PGPKeyPacket" type="xs:base64Binary"/>
+  <!-- End PGPData -->
+  <!-- Begin SPKIData -->
+  <xs:element name="SPKIData">
+    <xs:complexType>
+      <xs:sequence maxOccurs="unbounded">
+        <xs:element ref="ds:SPKISexp"/>
+        <xs:group minOccurs="0" maxOccurs="unbounded" ref="ds:anyOtherElement"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="SPKISexp" type="xs:base64Binary"/>
+  <!-- End SPKIData -->
+  <!-- End KeyInfo -->
+  <!-- Start Object (Manifest, SignatureProperty) -->
+  <xs:element name="Object">
+    <xs:complexType mixed="true">
+      <xs:sequence>
+        <xs:element ref="ds:SignatureProperties"/>
+        <xs:group minOccurs="0" maxOccurs="unbounded" ref="ds:anyElement"/>
+      </xs:sequence>
+      <xs:attribute name="Id" type="xs:ID"/>
+      <xs:attribute name="MimeType" type="xs:string"/>
+      <xs:attribute name="Encoding" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="Manifest">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element maxOccurs="unbounded" ref="ds:Reference"/>
+      </xs:sequence>
+      <xs:attribute name="Id" type="xs:ID"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="SignatureProperties">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element maxOccurs="unbounded" ref="ds:SignatureProperty"/>
+      </xs:sequence>
+      <xs:attribute name="Id" type="xs:ID"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="SignatureProperty">
+    <xs:complexType>
+      <xs:group maxOccurs="unbounded" ref="ds:anyOtherElement"/>
+      <xs:attribute name="Id" type="xs:ID"/>
+      <xs:attribute name="Target" use="required" type="xs:anyURI"/>
+    </xs:complexType>
+  </xs:element>
+  <!-- End Object (Manifest, SignatureProperty) -->
+  <!-- Start Algorithm Parameters -->
+  <xs:element name="HMACOutputLength" type="xs:integer"/>
+  <!-- Start KeyValue Element-types -->
+  <xs:element name="DSAKeyValue">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:sequence minOccurs="0">
+          <xs:element ref="ds:P"/>
+          <xs:element ref="ds:Q"/>
+        </xs:sequence>
+        <xs:element minOccurs="0" ref="ds:G"/>
+        <xs:element ref="ds:Y"/>
+        <xs:element minOccurs="0" ref="ds:J"/>
+        <xs:sequence minOccurs="0">
+          <xs:element ref="ds:Seed"/>
+          <xs:element ref="ds:PgenCounter"/>
+        </xs:sequence>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="P" type="ds:CryptoBinary"/>
+  <xs:element name="Q" type="ds:CryptoBinary"/>
+  <xs:element name="G" type="ds:CryptoBinary"/>
+  <xs:element name="Y" type="ds:CryptoBinary"/>
+  <xs:element name="J" type="ds:CryptoBinary"/>
+  <xs:element name="Seed" type="ds:CryptoBinary"/>
+  <xs:element name="PgenCounter" type="ds:CryptoBinary"/>
+  <xs:simpleType name="CryptoBinary">
+    <xs:restriction base="xs:base64Binary"/>
+  </xs:simpleType>
+  <xs:element name="RSAKeyValue">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element ref="ds:Modulus"/>
+        <xs:element ref="ds:Exponent"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="Modulus" type="ds:CryptoBinary"/>
+  <xs:element name="Exponent" type="ds:CryptoBinary"/>
+  <!-- End KeyValue Element-types -->
+  <!-- End Signature -->
+  <!-- Definitions for the *any* wild card and the *any other* wildcard -->
+  <xs:attributeGroup name="anyAttribute">
+    <xs:anyAttribute processContents="skip"/>
+  </xs:attributeGroup>
+  <xs:group name="anyElement">
+    <xs:sequence>
+      <xs:any processContents="skip"/>
+    </xs:sequence>
+  </xs:group>
+  <xs:group name="anyOtherElement">
+    <xs:choice>
+      <xs:any namespace="##other" processContents="skip"/>
+      <xs:any namespace="##local" processContents="skip"/>
+    </xs:choice>
+  </xs:group>
+</xs:schema>
+<!-- EOF -->
diff --git a/configuration/updates.xsd b/configuration/updates.xsd
new file mode 100644 (file)
index 0000000..6e6d88a
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.w3.org/ns/widgets" xmlns:widgets="http://www.w3.org/ns/widgets">
+    <xs:include schemaLocation="common.xsd"/>
+    <!--
+    Widget Updates <http://www.w3.org/TR/widgets-updates/>
+    requires common.rnc
+    -->
+    <xs:element name="update-description">
+    <xs:complexType mixed="true">
+        <xs:group minOccurs="0" maxOccurs="unbounded" ref="widgets:foreignElement"/>
+        <xs:attributeGroup ref="widgets:foreignAttribute"/>
+        <xs:attribute name="href" use="required" type="xs:anyURI"/>
+    </xs:complexType>
+    </xs:element>
+</xs:schema>
diff --git a/configuration/validate-config.xml.sh b/configuration/validate-config.xml.sh
new file mode 100755 (executable)
index 0000000..a242910
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+xmllint --schema widgets.xsd config.xml
diff --git a/configuration/widgets.tizen.xsd b/configuration/widgets.tizen.xsd
new file mode 100755 (executable)
index 0000000..e849e30
--- /dev/null
@@ -0,0 +1,341 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Widget Configuration Document Extensions XSD For TIZEN -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tizen="http://tizen.org/ns/widgets" targetNamespace="http://tizen.org/ns/widgets">
+    <xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
+    <xs:simpleType name="data.boolean">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="true"/>
+            <xs:enumeration value="false"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="appserviceOperationType">
+        <xs:restriction base="xs:anyURI"/>
+    </xs:simpleType>
+
+    <xs:simpleType name="PackageType">
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[0-9a-zA-Z]{10}"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="applicationIdType">
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[0-9a-zA-Z]{10}[.][0-9a-zA-Z]{1,52}"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="screenOrientationType">
+        <xs:restriction base="xs:token">
+            <xs:enumeration value="portrait"/>
+            <xs:enumeration value="landscape"/>
+            <xs:enumeration value="auto-rotation"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="activationType">
+        <xs:restriction base="xs:token">
+            <xs:enumeration value="enable"/>
+            <xs:enumeration value="disable"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="soundmodeType">
+        <xs:restriction base="xs:token">
+            <xs:enumeration value="shared"/>
+            <xs:enumeration value="exclusive"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="appWidgetIdType">
+        <xs:restriction base="xs:string">
+            <xs:pattern value="[0-9a-zA-Z]{10}.[0-9a-zA-Z]{1,52}.[0-9a-zA-Z]{1,}"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:simpleType name="updatePeriodType">
+        <xs:restriction base="xs:float">
+            <xs:minInclusive value="1800"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+<!-- unecessary for tizenw
+    <xs:element name="content">
+        <xs:complexType>
+            <xs:attribute name="src" use="required" type="xs:anyURI"/>
+        </xs:complexType>
+    </xs:element>
+-->
+
+    <xs:element name="application">
+        <xs:complexType>
+            <xs:attribute name="id" type="tizen:applicationIdType" use="required"/>
+            <xs:attribute name="package" type="tizen:PackageType" use="required"/>
+            <xs:attribute name="required_version" type="xs:string" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+<!-- IME_ENABLED -->
+    <xs:element name="ime">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element ref="tizen:uuid" minOccurs="1" maxOccurs="1"/>
+                <xs:element ref="tizen:languages" minOccurs="1" maxOccurs="1">
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="languages">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element ref="tizen:language" minOccurs="1" maxOccurs="unbounded"/>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="uuid" type="xs:string"/>
+    <xs:element name="language" type="xs:string"/>
+
+<!-- SERVICE_ENABLED -->
+    <xs:element name="service">
+        <xs:complexType>
+            <xs:all>
+                <xs:element ref="tizen:service-content" minOccurs="1" maxOccurs="1"/>
+                <xs:element ref="tizen:service-name" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element ref="tizen:service-icon" minOccurs="0" maxOccurs="unbounded"/>
+                <xs:element ref="tizen:service-description" minOccurs="0" maxOccurs="unbounded"/>
+            </xs:all>
+            <xs:attribute name="id" type="tizen:applicationIdType" use="required"/>
+            <xs:attribute name="on_boot" type="tizen:data.boolean" use="optional"/>
+            <xs:attribute name="auto_restart" type="tizen:data.boolean" use="optional"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="service-name">
+        <xs:complexType mixed="true">
+            <xs:attribute ref="xml:lang"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="service-description">
+        <xs:complexType mixed="true">
+            <xs:attribute ref="xml:lang"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="service-icon">
+        <xs:complexType>
+            <xs:attribute name="src" use="required" type="xs:anyURI"/>
+            <xs:attribute name="width" use="optional" type="xs:int"/>
+            <xs:attribute name="height" use="optional" type="xs:int"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="service-content">
+        <xs:complexType>
+            <xs:attribute name="src" use="required" type="xs:anyURI"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="setting">
+        <xs:complexType>
+<!-- unecessary for tizenw
+            <xs:attribute name="screen-orientation" type="tizen:screenOrientationType" use="optional"/> default: portrait
+-->
+<!-- unecessary for tizenw
+            <xs:attribute name="context-menu" type="tizen:activationType" use="optional"/> default: enable
+-->
+            <xs:attribute name="background-support" type="tizen:activationType" use="optional" default="disable"/>
+            <xs:attribute name="encryption" type="tizen:activationType" use="optional" default="disable"/>
+<!-- unecessary for tizenw
+            <xs:attribute name="install-location" type="tizen:InstallLocationType" use="optional"/>
+            <xs:attribute name="nodisplay" type="tizen:data.boolean" use="optional"/> default: false
+-->
+<!-- unecessary for tizenw
+            <xs:attribute name="indicator-persence" type="tizen:data.boolean" use="optional"/>
+            <xs:attribute name="backbutton-persence" type="tizen:data.boolean" use="optional"/>
+            <xs:attribute name="user-agent" use="optional"/>
+-->
+            <xs:attribute name="hwkey-event" type="tizen:activationType" use="optional" default="enable"/> <!-- default: true -->
+<!-- unecessary for tizenw
+            <xs:attribute name="sound-mode" type="tizen:soundmodeType" use="optional"/> default: shared
+-->
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="app-control">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:choice maxOccurs="unbounded">
+            <xs:element ref="tizen:src"/>
+            <xs:element ref="tizen:operation"/>
+            <xs:element ref="tizen:uri"/>
+            <xs:element ref="tizen:mime"/>
+          </xs:choice>
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="src">
+        <xs:complexType>
+            <xs:attribute name="name" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="operation">
+        <xs:complexType>
+            <xs:attribute name="name" type="tizen:appserviceOperationType" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="uri">
+        <xs:complexType>
+            <xs:attribute name="name" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="mime">
+      <xs:complexType>
+        <xs:attribute name="name" use="required"/>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="privilege">
+        <xs:complexType>
+            <xs:attribute name="name" use="required" type="xs:anyURI"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="content-security-policy">
+        <xs:complexType  mixed="true">
+        </xs:complexType>
+    </xs:element>
+
+<!-- unecessary fro tizenw
+    <xs:element name="content-security-policy-report-only">
+        <xs:complexType  mixed="true">
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="allow-navigation">
+        <xs:complexType  mixed="true">
+        </xs:complexType>
+    </xs:element>
+-->
+
+    <xs:element name="app-widget">
+        <xs:complexType mixed="true">
+            <xs:sequence>
+                <xs:element ref="tizen:box-label" minOccurs="1" maxOccurs="unbounded"/>
+                <xs:element ref="tizen:box-icon" minOccurs="1" maxOccurs="1"/>
+                <xs:element ref="tizen:box-content" minOccurs="1" maxOccurs="1"/>
+            </xs:sequence>
+            <xs:attribute name="id" type="tizen:appWidgetIdType" use="required"/>
+            <xs:attribute name="primary" type="tizen:data.boolean" use="required"/>
+            <xs:attribute name="auto-launch" type="tizen:data.boolean" use="optional"/>
+            <xs:attribute name="update-period" type="tizen:updatePeriodType" use="optional"/>
+            <xs:attribute name="type" type="xs:string" use="optional"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="box-label">
+        <xs:complexType mixed="true">
+            <xs:attribute ref="xml:lang"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="box-icon">
+        <xs:complexType>
+        <xs:attribute name="src" use="required" type="xs:anyURI"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="box-content">
+        <xs:complexType mixed="true">
+            <xs:sequence>
+                <xs:element ref="tizen:box-size" minOccurs="1" maxOccurs="5"/>
+                <xs:element ref="tizen:pd" minOccurs="0" maxOccurs="1"/>
+            </xs:sequence>
+            <xs:attribute name="src" use="required" type="xs:anyURI"/>
+            <xs:attribute name="mouse-event" use="optional" type="tizen:data.boolean"/>
+            <xs:attribute name="touch-effect" use="optional" type="tizen:data.boolean"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="pd">
+        <xs:complexType>
+            <xs:attribute name="src" use="required" type="xs:anyURI"/>
+            <xs:attribute name="width" use="required" type="xs:int"/>
+            <xs:attribute name="height" use="required" type="xs:int"/>
+            <xs:attribute name="fast-open" use="optional" type="tizen:data.boolean"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="box-size">
+        <xs:complexType mixed="true">
+        <xs:attribute name="preview" use="optional" type="xs:anyURI"/>
+        <xs:attribute name="use-decoration" use="optional" type="tizen:data.boolean"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:simpleType name="InstallLocationType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="auto"/>
+            <xs:enumeration value="internal-only"/>
+            <xs:enumeration value="prefer-external"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:element name="capability">
+        <xs:complexType mixed="true">
+        </xs:complexType>
+    </xs:element>
+
+<!-- unecessary for tizenw
+    <xs:element name="account">
+        <xs:complexType mixed="true">
+            <xs:sequence>
+                <xs:choice maxOccurs="unbounded">
+                    <xs:element ref="tizen:icon" />
+                    <xs:element ref="tizen:display-name" />
+                    <xs:element ref="tizen:capability" />
+                </xs:choice>
+            </xs:sequence>
+        <xs:attribute name="multiple-account-support" use="required" type="tizen:data.boolean"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="icon">
+      <xs:complexType mixed="true">
+        <xs:attribute name="section" use="required" type="xs:string"/>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="display-name">
+      <xs:complexType mixed="true">
+        <xs:attribute ref="xml:lang"/>
+      </xs:complexType>
+    </xs:element>
+-->
+
+    <xs:element name="metadata">
+        <xs:complexType>
+            <xs:attribute name="key" type="xs:string" use="required"/>
+            <xs:attribute name="value" type="xs:string"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="splash">
+        <xs:complexType>
+            <xs:attribute name="src" type="xs:string" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:element name="category">
+        <xs:complexType>
+            <xs:attribute name="name" type="xs:string" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+</xs:schema>
diff --git a/configuration/widgets.xsd b/configuration/widgets.xsd
new file mode 100644 (file)
index 0000000..8de2f3d
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  RELAX NG Schema for the Widgets Family of Specifications
+  
+  This document is non-normative.
+  
+  The following is a RELAX NG schema representation of the elements,
+  and attributes, that can be used in a widget's configuration document.
+  
+  A conformance checker may use the RELAX NG for the configuration document to validate
+  elements and attributes of a configuration document within the limits of the RELAX NG
+  specification.
+  
+  Authors: David H�s�ther, Marcos C�ceres, Robin Berjon
+  Contact: public-webapps@w3.org if you find any errors or have any questions
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.w3.org/ns/widgets" xmlns:widgets="http://www.w3.org/ns/widgets">
+    <xs:include schemaLocation="packaging-configuration.xsd"/>
+    <xs:import schemaLocation="common.xsd"/>
+</xs:schema>
diff --git a/configuration/xml.xsd b/configuration/xml.xsd
new file mode 100644 (file)
index 0000000..715330a
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:widgets="http://www.w3.org/ns/widgets" xmlns:its="http://www.w3.org/2005/11/its"  targetNamespace="http://www.w3.org/XML/1998/namespace" elementFormDefault="qualified">
+    <xs:attribute name="lang" type="xs:language"/>
+</xs:schema>
diff --git a/packaging/wrt-installer.spec b/packaging/wrt-installer.spec
new file mode 100755 (executable)
index 0000000..11630ec
--- /dev/null
@@ -0,0 +1,135 @@
+#git:framework/web/wrt-installer
+Name:       wrt-installer
+Summary:    Installer for tizen Webruntime
+Version:    0.1.175_w11
+Release:    1
+Group:      Development/Libraries
+License:    Apache License, Version 2.0
+URL:        N/A
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires:  cmake
+BuildRequires:  edje-tools
+BuildRequires:  pkgconfig(appsvc)
+BuildRequires:  pkgconfig(libxml-2.0)
+BuildRequires:  pkgconfig(openssl)
+BuildRequires:  pkgconfig(dpl-efl)
+BuildRequires:  pkgconfig(cert-svc-vcore)
+BuildRequires:  pkgconfig(dpl-event-efl)
+BuildRequires:  pkgconfig(dpl-utils-efl)
+BuildRequires:  pkgconfig(dpl-wrt-dao-ro)
+BuildRequires:  pkgconfig(dpl-wrt-dao-rw)
+BuildRequires:  pkgconfig(wrt-commons-i18n-dao-ro)
+BuildRequires:  pkgconfig(wrt-commons-widget-interface-dao)
+BuildRequires:  pkgconfig(security-install)
+BuildRequires:  pkgconfig(ecore-x)
+BuildRequires:  pkgconfig(xmlsec1)
+BuildRequires:  pkgconfig(libidn)
+BuildRequires:  pkgconfig(libiri)
+BuildRequires:  pkgconfig(libpcrecpp)
+BuildRequires:  pkgconfig(pkgmgr-installer)
+BuildRequires:  pkgconfig(pkgmgr-parser)
+BuildRequires:  pkgconfig(pkgmgr-types)
+BuildRequires:  pkgconfig(pkgmgr-info)
+BuildRequires:  pkgconfig(pkgmgr)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(cert-svc)
+BuildRequires:  pkgconfig(utilX)
+BuildRequires:  pkgconfig(wrt-plugins-types)
+BuildRequires:  pkgconfig(tapi)
+BuildRequires:  pkgconfig(shortcut)
+BuildRequires:  pkgconfig(capi-appfw-app-manager)
+BuildRequires:  pkgconfig(capi-system-power)
+BuildRequires:  pkgconfig(app2sd)
+BuildRequires:  pkgconfig(web-provider)
+BuildRequires:  pkgconfig(libprivilege-control)
+BuildRequires:  pkgconfig(libsmack)
+BuildRequires:  libss-client-devel
+BuildRequires:  boost-devel
+Requires: libss-client
+Requires: xmlsec1
+Requires: wrt-plugins-tizen
+
+%description
+Description: Wrt Installer for Tizen apps and Wac apps
+
+%prep
+%setup -q
+
+%define with_tests 0
+%if "%{WITH_TESTS}" == "ON" || "%{WITH_TESTS}" == "Y" || "%{WITH_TESTS}" == "YES" || "%{WITH_TESTS}" == "TRUE" || "%{WITH_TESTS}" == "1"
+    %define with_tests 1
+%endif
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+
+%if "%{_repository}" == "wearable"
+    %define device_profile wearable
+%else
+    %define device_profile mobile
+%endif
+
+export LDFLAGS+="-Wl,--rpath=/usr/lib -Wl,--hash-style=both -Wl,--as-needed"
+LDFLAGS="$LDFLAGS"
+
+%if "%{_repository}" == "wearable"
+    ln -sf src_wearable src
+%else
+    ln -sf src_mobile src
+%endif
+
+cmake . -DCMAKE_INSTALL_PREFIX=/usr \
+        -DDPL_LOG=ON \
+        -DLB_SUPPORT=ON \
+        -DCMAKE_BUILD_TYPE=%{?build_type:%build_type} \
+        -DDEVICE_PROFILE=%{?device_profile:%device_profile} \
+        %{?WITH_TESTS:-DWITH_TESTS=%WITH_TESTS}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+%post
+/sbin/ldconfig
+
+#symlink for package manager
+%define pkg_manager_backend_path "/usr/etc/package-manager/backend"
+ln -sf /usr/bin/wrt-installer %{pkg_manager_backend_path}/wgt
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/Wgt
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/wGt
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/wgT
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/WGt
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/wGT
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/WgT
+ln -sf %{pkg_manager_backend_path}/wgt %{pkg_manager_backend_path}/WGT
+
+#for booting recovery
+mkdir -p /opt/share/widget/temp_info
+
+# for downloadable Application icons path
+mkdir -p /opt/share/icons/default/small
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest wrt-installer.manifest
+%attr(755,root,root) %{_bindir}/wrt-installer
+/usr/etc/package-manager/backendlib/libwgt.so
+%attr(644,root,root) /usr/etc/wrt-installer/*.xsd
+%{_datadir}/license/%{name}
+%if %{with_tests}
+    %attr(755,root,root) %{_bindir}/wrt-installer-tests-*
+    /opt/share/widget/tests/installer/widgets/*
+    /opt/share/widget/tests/installer/configs/*
+%endif
+%{_sysconfdir}/smack/accesses2.d/wrt-installer.rule
diff --git a/src_mobile/CMakeLists.txt b/src_mobile/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bd52dcf
--- /dev/null
@@ -0,0 +1,185 @@
+# 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")
+
+OPTION(LB_SUPPORT "lb support" OFF)
+
+SET(INSTALLER_SRC_DIR
+    ${PROJECT_SOURCE_DIR}/src_mobile
+    )
+
+SET(INSTALLER_CONFIG_PARSER
+    ${INSTALLER_SRC_DIR}/configuration_parser
+    )
+
+SET(INSTALLER_JOBS
+    ${INSTALLER_SRC_DIR}/jobs
+    )
+
+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}/commons
+    ${INSTALLER_SRC_DIR}/pkg-manager
+)
+
+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}/libiriwrapper.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/manifest.cpp
+    ${INSTALLER_JOBS}/widget_install/task_commons.cpp
+    ${INSTALLER_JOBS}/widget_install/task_process_config.cpp
+    ${INSTALLER_JOBS}/widget_install/task_database.cpp
+    ${INSTALLER_JOBS}/widget_install/task_configuration.cpp
+    ${INSTALLER_JOBS}/widget_install/ace_registration.cpp
+    ${INSTALLER_JOBS}/widget_install/task_file_manipulation.cpp
+    ${INSTALLER_JOBS}/widget_install/task_user_data_manipulation.cpp
+    ${INSTALLER_JOBS}/widget_install/task_smack.cpp
+    ${INSTALLER_JOBS}/widget_install/task_ace_check.cpp
+    ${INSTALLER_JOBS}/widget_install/task_manifest_file.cpp
+    ${INSTALLER_JOBS}/widget_install/task_certify.cpp
+    ${INSTALLER_JOBS}/widget_install/task_certify_level.cpp
+    ${INSTALLER_JOBS}/widget_install/task_prepare_files.cpp
+    ${INSTALLER_JOBS}/widget_install/task_recovery.cpp
+    ${INSTALLER_JOBS}/widget_install/task_install_ospsvc.cpp
+    ${INSTALLER_JOBS}/widget_install/task_update_files.cpp
+    ${INSTALLER_JOBS}/widget_install/task_remove_backup.cpp
+    ${INSTALLER_JOBS}/widget_install/task_encrypt_resource.cpp
+    ${INSTALLER_JOBS}/widget_install/task_prepare_reinstall.cpp
+    ${INSTALLER_JOBS}/widget_install/task_pkg_info_update.cpp
+    ${INSTALLER_JOBS}/widget_install/widget_security.cpp
+    ${INSTALLER_JOBS}/widget_install/widget_update_info.cpp
+    ${INSTALLER_JOBS}/widget_install/directory_api.cpp
+    ${INSTALLER_JOBS}/widget_install/widget_unzip.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_remove_custom_handlers.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_db_update.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_smack.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_uninstall_ospsvc.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_delete_pkginfo.cpp
+    ${INSTALLER_SRC_DIR}/logic/installer_logic.cpp
+    ${INSTALLER_SRC_DIR}/logic/installer_controller.cpp
+    ${INSTALLER_SRC_DIR}/misc/wac_widget_id.cpp
+    ${INSTALLER_SRC_DIR}/misc/feature_logic.cpp
+    ${INSTALLER_SRC_DIR}/misc/libxml_utils.cpp
+    ${INSTALLER_SRC_DIR}/misc/widget_location.cpp
+    ${INSTALLER_SRC_DIR}/misc/widget_install_to_external.cpp
+    ${INSTALLER_SRC_DIR}/misc/plugin_path.cpp
+    ${INSTALLER_SRC_DIR}/pkg-manager/pkgmgr_signal.cpp
+    )
+
+IF(LB_SUPPORT)
+    SET(INSTALLER_SOURCES
+        ${INSTALLER_SOURCES}
+        )
+    MESSAGE(STATUS "adding definition -DLB_SUPPORT")
+    ADD_DEFINITIONS("-DLB_SUPPORT")
+ENDIF(LB_SUPPORT)
+
+MESSAGE(STATUS "add -DSEP_INSTALLER")
+ADD_DEFINITIONS("-DSEP_INSTALLER")
+
+
+PKG_CHECK_MODULES(INSTALLER_STATIC_DEP
+    dpl-efl
+    dpl-event-efl
+    dpl-utils-efl
+    dpl-wrt-dao-ro
+    dpl-wrt-dao-rw
+    wrt-commons-custom-handler-dao-rw
+    wrt-commons-security-origin-dao
+    wrt-commons-widget-interface-dao
+    wrt-plugins-types
+    pkgmgr-installer
+    pkgmgr-parser
+    pkgmgr-info
+    web-provider
+    libsmack
+    REQUIRED
+)
+
+PKG_CHECK_MODULES(SYS_INSTALLER_STATIC_DEP
+    appsvc
+    libxml-2.0
+    openssl
+    cert-svc-vcore
+    security-install
+    ecore-x
+    xmlsec1
+    libidn
+    libiri
+    libpcrecpp
+    ail
+    elementary
+    tapi
+    shortcut
+    capi-appfw-app-manager
+    app2sd
+    libprivilege-control
+    REQUIRED
+)
+
+INCLUDE_DIRECTORIES( SYSTEM ${SYS_INSTALLER_STATIC_DEP_INCLUDE_DIRS})
+
+INCLUDE_DIRECTORIES(
+    ${INSTALLER_DEP_INCLUDES}
+    ${INSTALLER_INCLUDES}
+    ${INSTALLER_STATIC_DEP_INCLUDE_DIRS}
+    ${OSP_APPFW_INCLUDES}
+    )
+
+ADD_LIBRARY(${TARGET_INSTALLER_STATIC} STATIC
+    ${INSTALLER_SOURCES}
+    )
+
+ADD_DEFINITIONS(${INSTALLER_STATIC_DEP_CFLAGS})
+ADD_DEFINITIONS(${INSTALLER_STATIC_DEP_CFLAGS_OTHERS})
+ADD_DEFINITIONS(${SYS_INSTALLER_STATIC_DEP_CFLAGS})
+ADD_DEFINITIONS(${SYS_INSTALLER_STATIC_DEP_CFLAGS_OTHERS})
+
+TARGET_LINK_LIBRARIES(${TARGET_INSTALLER_STATIC}
+    ${INSTALLER_STATIC_DEP_LIBRARIES} "-ldl"
+    ${SYS_INSTALLER_STATIC_DEP_LIBRARIES} "-ldl"
+    )
+
+#for encryption
+TARGET_LINK_LIBRARIES(${TARGET_INSTALLER_STATIC} "-lss-client" )
+
+ADD_SUBDIRECTORY(pkg-manager)
+ADD_SUBDIRECTORY(wrt-installer)
diff --git a/src_mobile/DESCRIPTION b/src_mobile/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_mobile/commons/installer_log.h b/src_mobile/commons/installer_log.h
new file mode 100644 (file)
index 0000000..6ba4137
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013 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_log.h
+ * @author     Sungsu Kim(sung-su.kim@samsung.com)
+ * @version    0.1
+ * @brief
+ */
+
+#ifndef INSTALLER_LOG_H
+#define INSTALLER_LOG_H
+
+#include <dpl/log/secure_log.h>
+
+#ifdef WRT_INSTALLER_LOG
+
+#undef COLOR_WARNING
+#define COLOR_WARNING "\e[0m"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[0m"
+
+#endif
+
+#endif // INSTALLER_LOG_H
+
diff --git a/src_mobile/commons/wrt_common_types.h b/src_mobile/commons/wrt_common_types.h
new file mode 100644 (file)
index 0000000..d9ea0f0
--- /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.
+ */
+/*
+ * 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::DbWidgetFeature WidgetFeature;
+typedef WrtDB::DbWidgetFeatureSet WidgetFeatureSet;
+
+typedef WrtDB::DbWidgetSize WidgetSize;
+
+typedef WrtDB::DbPluginHandle PluginHandle;
+
+enum InstallLocationType
+{
+    INSTALL_LOCATION_TYPE_UNKNOWN = 0,
+    INSTALL_LOCATION_TYPE_INTERNAL_ONLY,
+    INSTALL_LOCATION_TYPE_AUTO,
+    INSTALL_LOCATION_TYPE_PREFER_EXTERNAL,
+};
+
+#endif /* PLUGIN_COMMON_TYPES_H */
diff --git a/src_mobile/commons/wrt_error.h b/src_mobile/commons/wrt_error.h
new file mode 100644 (file)
index 0000000..ae4f2de
--- /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_INVALID_APP_ID = WRT_WM_ERRCODE + WRT_ERROR_SET(0x11),
+
+    /* 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_mobile/commons/wrt_install_mode.h b/src_mobile/commons/wrt_install_mode.h
new file mode 100644 (file)
index 0000000..714d3c3
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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_install_mode.h
+ * @author  Jihoon Chung (jihoon.chung@samgsung.com)
+ * @version
+ * @brief   Definition file of widget install mode class
+ */
+
+#ifndef WRT_INSTALL_MODE_H
+#define WRT_INSTALL_MODE_H
+
+class InstallMode
+{
+  public:
+    enum class Command
+    {
+        INSTALL,
+        REINSTALL
+    };
+    enum class Location
+    {
+        INTERNAL,
+        EXTERNAL
+    };
+    enum class RootPath
+    {
+        RW,
+        RO
+    };
+    enum class ExtensionType
+    {
+        WGT,
+        DIR
+    };
+    enum class InstallTime
+    {
+        NORMAL,
+        CSC,
+        PRELOAD,
+    };
+
+    InstallMode(Command cmd = Command::INSTALL,
+                Location lo = Location::INTERNAL,
+                RootPath root = RootPath::RW,
+                ExtensionType extensionType = ExtensionType::WGT,
+                InstallTime time = InstallTime::NORMAL) :
+        command(cmd),
+        location(lo),
+        rootPath(root),
+        extension(extensionType),
+        installTime(time),
+        removable(true)
+    {};
+
+    Command command;
+    Location location;
+    RootPath rootPath;
+    ExtensionType extension;
+    InstallTime installTime;
+    bool removable;
+};
+
+#endif // WRT_INSTALL_MODE_H
+
diff --git a/src_mobile/configuration_parser/deny_all_parser.cpp b/src_mobile/configuration_parser/deny_all_parser.cpp
new file mode 100644 (file)
index 0000000..e807d5e
--- /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.
+ */
+#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_mobile/configuration_parser/deny_all_parser.h b/src_mobile/configuration_parser/deny_all_parser.h
new file mode 100644 (file)
index 0000000..d9dfe56
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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_mobile/configuration_parser/element_parser.h b/src_mobile/configuration_parser/element_parser.h
new file mode 100644 (file)
index 0000000..a44f94a
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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 <memory>
+
+#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 prefix;
+    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 std::shared_ptr<ElementParser> ElementParserPtr;
+
+class ElementParser : public std::enable_shared_from_this<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_mobile/configuration_parser/ignoring_parser.cpp b/src_mobile/configuration_parser/ignoring_parser.cpp
new file mode 100644 (file)
index 0000000..29520d5
--- /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        ignoring_parser.cpp
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+#include "ignoring_parser.h"
+
+#include <memory>
+
+IgnoringParser::IgnoringParser() : ElementParser()
+{}
+
+ElementParserPtr IgnoringParser::Create()
+{
+    return ElementParserPtr(new IgnoringParser());
+}
+
+ElementParserPtr IgnoringParser::Reuse()
+{
+    return shared_from_this();
+}
+
+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_mobile/configuration_parser/ignoring_parser.h b/src_mobile/configuration_parser/ignoring_parser.h
new file mode 100644 (file)
index 0000000..b14f1ad
--- /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_mobile/configuration_parser/libiriwrapper.cpp b/src_mobile/configuration_parser/libiriwrapper.cpp
new file mode 100644 (file)
index 0000000..6d8de2a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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_mobile/configuration_parser/libiriwrapper.h b/src_mobile/configuration_parser/libiriwrapper.h
new file mode 100644 (file)
index 0000000..b0b3e86
--- /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_mobile/configuration_parser/parser_runner.cpp b/src_mobile/configuration_parser/parser_runner.cpp
new file mode 100644 (file)
index 0000000..725cd77
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * 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 "stdio.h"
+
+#include <stack>
+#include <libxml/xmlreader.h>
+#include <dpl/binary_queue.h>
+#include <dpl/assert.h>
+#include <dpl/file_input.h>
+
+#include <installer_log.h>
+
+class ParserRunner::Impl
+{
+    static void logErrorLibxml2(void *, const char *msg, ...)
+    {
+        char buffer[300];
+        va_list args;
+        va_start(args, msg);
+        vsnprintf(buffer, 300, msg, args);
+        va_end(args);
+        _E("%s", buffer);
+    }
+
+    static void logWarningLibxml2(void *, const char *msg, ...)
+    {
+        char buffer[300];
+        va_list args;
+        va_start(args, msg);
+        vsnprintf(buffer, 300, msg, args);
+        va_end(args);
+        _W("%s", buffer);
+    }
+
+  public:
+    bool Validate(const std::string& filename, const std::string& schema)
+    {
+        int ret = -1;
+        xmlSchemaParserCtxtPtr ctx;
+        xmlSchemaValidCtxtPtr vctx;
+        xmlSchemaPtr xschema;
+        ctx = xmlSchemaNewParserCtxt(schema.c_str());
+        if (ctx == NULL) {
+            _E("xmlSchemaNewParserCtxt() Failed");
+            return false;
+        }
+        xschema = xmlSchemaParse(ctx);
+        if (xschema == NULL) {
+            _E("xmlSchemaParse() Failed");
+            return false;
+        }
+        vctx = xmlSchemaNewValidCtxt(xschema);
+        if (vctx == NULL) {
+            _E("xmlSchemaNewValidCtxt() Failed");
+            return false;
+        }
+        xmlSchemaSetValidErrors(vctx, (xmlSchemaValidityErrorFunc)&logErrorLibxml2, (xmlSchemaValidityWarningFunc) &logWarningLibxml2, NULL);
+        ret = xmlSchemaValidateFile(vctx, filename.c_str(), 0);
+        if (ret == -1) {
+            _E("xmlSchemaValidateFile() failed");
+            return false;
+        } else if (ret == 0) {
+            _E("Config is Valid");
+            return true;
+        } else {
+            _E("Config Validation Failed with error code %d", ret);
+            return false;
+        }
+        return true;
+    }
+
+    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:
+                    _W("Ignoring Node of Type: %d", xmlTextReaderNodeType(m_reader));
+                    break;
+                }
+
+                if (m_parsingError) {
+                    _E("Parsing error occured: %ls", m_errorMsg.c_str());
+                    ThrowMsg(ElementParser::Exception::ParseError, m_errorMsg);
+                }
+            }
+
+            if (m_parsingError) {
+                _E("Parsing error occured: %ls", m_errorMsg.c_str());
+                ThrowMsg(ElementParser::Exception::ParseError, m_errorMsg);
+            }
+
+            while (!m_stack.empty()) {
+                VerifyAndRemoveCurrentElementParser();
+            }
+        }
+        Catch(ElementParser::Exception::Base)
+        {
+            CleanupParserRunner();
+            _E("%s", _rethrown_exception.DumpToString().c_str());
+            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.value = GetValue();
+        element.lang = GetLanguageTag();
+        element.ns = GetNamespace();
+
+        _D("value: %ls, lang: %ls, ns: %ls)",
+            element.value.c_str(), element.lang.c_str(), element.ns.c_str());
+
+        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.ns = GetAttributeNamespace();
+            attribute.prefix = GetNamePrefix();
+            attribute.name = GetNameWithoutNamespace();
+            attribute.value = GetValue();
+            attribute.lang = GetLanguageTag();
+            _D("Attribute name: %ls, value: %ls, prefix: %ls, namespace: %ls, lang: %ls",
+                attribute.name.c_str(), attribute.value.c_str(), attribute.prefix.c_str(),
+                attribute.ns.c_str(), attribute.lang.c_str());
+            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 GetAttributeNamespace() const
+    {
+        DPL::String ret_value;
+        const xmlChar* value = xmlTextReaderLookupNamespace(m_reader, NULL);
+        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 GetNamePrefix() const
+    {
+        DPL::String ret_value;
+        const xmlChar* value = xmlTextReaderPrefix(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)
+    {
+        _E("LibXML:  %ls", msg.c_str());
+        m_parsingError = true;
+        m_errorMsg = m_errorMsg + DPL::FromASCIIString("\n");
+        m_errorMsg = m_errorMsg + msg;
+    }
+
+    void StructuredErrorHandler(xmlErrorPtr error)
+    {
+        _E("LibXML:  %s", 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())
+{}
+
+bool ParserRunner::Validate(const std::string& filename, const std::string& schema)
+{
+    return m_impl->Validate(filename, schema);
+}
+
+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_mobile/configuration_parser/parser_runner.h b/src_mobile/configuration_parser/parser_runner.h
new file mode 100644 (file)
index 0000000..c5c0714
--- /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        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:
+    bool Validate(const std::string& filename, const std::string& schema);
+
+    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_mobile/configuration_parser/root_parser.h b/src_mobile/configuration_parser/root_parser.h
new file mode 100644 (file)
index 0000000..65bae87
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 <installer_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*/)
+    {
+        _D("element");
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {
+        _D("attribute");
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        _D("text");
+    }
+
+    virtual void Verify()
+    {
+        _D("");
+    }
+
+  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_mobile/configuration_parser/widget_parser.cpp b/src_mobile/configuration_parser/widget_parser.cpp
new file mode 100644 (file)
index 0000000..e00b84e
--- /dev/null
@@ -0,0 +1,2949 @@
+/*
+ * 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 <algorithm>
+#include <cerrno>
+#include <climits>
+#include <cmath>
+#include <cstdlib>
+#include <cstdio>
+#include <locale>
+#include <memory>
+#include <string>
+
+#include <iri.h>
+#include <pcrecpp.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 <dpl/fast_delegate.h>
+#include <dpl/foreach.h>
+
+#include <installer_log.h>
+
+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 {
+        _W("dir attribute has wrong value: %ls ", attribute.value.c_str());
+        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);
+        break;
+    }
+}
+} // 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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+  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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+  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_WARP
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return DPL::MakeDelegate(this, &AccessParser::Other);
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        // for tizen web apps WARP should be used
+        if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
+            element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_standardType = STANDARD_TYPE_WARP;
+        }
+    }
+
+    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;
+            }
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        switch (m_standardType) {
+        case STANDARD_TYPE_WARP:
+            AcceptWac(attribute);
+            break;
+        default:
+            _E("Error in Access tag - unknown standard.");
+            break;
+        }
+    }
+
+    void VerifyWac()
+    {
+        WarpIRI iri;
+        iri.set(m_strIRIOrigin, false);
+
+        if (!iri.isAccessDefinition()) {
+            _W("Access list element: %ls is not acceptable by WARP standard and will be ignored!",
+                m_strIRIOrigin.c_str());
+            return;
+        }
+
+        if(m_strIRIOrigin == L"*") //wildcard match means yes for subdomains
+        {
+            m_bSubDomainAccess = true;
+        }
+
+        ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
+                                                m_bSubDomainAccess);
+        //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
+        m_data.accessInfoSet.insert(accessInfo);
+    }
+
+    virtual void Verify()
+    {
+        switch (m_standardType) {
+        case STANDARD_TYPE_WARP:
+            VerifyWac();
+            break;
+        default:
+            _E("Error in Access tag - unknown standard.");
+            break;
+        }
+    }
+
+    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(shared_from_this())));
+    }
+
+  private:
+    DPL::String m_strIRIOrigin;
+    bool m_bSubDomainAccess;
+    StandardType m_standardType;
+    bool m_network;
+    ConfigParserData& m_data;
+};
+
+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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+    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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+  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(shared_from_this())));
+    }
+
+  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
+{
+    DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
+
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    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()) {
+            _W("src attribute of icon element is mandatory - ignoring");
+            return;
+        }
+
+        Try
+        {
+            ConfigParserData::Icon icon(delocalizeSrcPath(*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);
+            }
+        }
+        Catch(BadSrcError)
+        {
+            _W("src attribute is invalid: %ls", (*m_src).c_str());
+        }
+    }
+
+  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;
+    }
+
+    /**
+     * @brief delocalizePath removes locales folder from relative path if
+     * neccessary
+     * @param source source string
+     *
+     * @throw BadSrcError if string is bad value of src attribute
+     *
+     * @return corrected string
+     */
+    static DPL::String delocalizeSrcPath(const DPL::String & source)
+    {
+        static const DPL::String localeFolder(L"locales/");
+        static const int index = localeFolder.size();
+
+        DPL::String result = source;
+
+        if (source.substr(0, index) == localeFolder) {
+            size_t pos = result.find_first_of('/', index);
+            if (pos != std::string::npos && pos + 1 < source.size()) {
+                result = result.substr(pos + 1, source.size());
+            } else {
+                Throw(BadSrcError);
+            }
+        }
+        return result;
+    }
+};
+
+class ContentParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    ContentParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        m_namespace = element.ns;
+    }
+
+    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.IsNull())
+            {
+                m_encoding = mimeAttributes[L"charset"];
+            }
+        } else if (attribute.name == L"encoding") {
+            if (!value.empty()) {
+                m_encoding = value;
+            }
+        }
+    }
+
+    virtual void Verify()
+    {
+        if(!!m_data.startFileEncountered)
+        {
+            if(m_data.startFileNamespace == m_namespace
+                || m_namespace != ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                return;
+            }
+            //else continue -> if previous item was not in tizen namespace
+        }
+
+        m_data.startFileEncountered = true;
+        m_data.startFileNamespace = m_namespace;
+
+        //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) {
+                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;
+    DPL::String m_namespace;
+};
+
+class PreferenceParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    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()) {
+            _W("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 SettingParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    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 AppControlParser : public ElementParser
+{
+  public:
+    struct SourceParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (m_value.IsNull() || *m_value == L"") {
+                return;
+            }
+
+            m_data.m_src = *m_value;
+        }
+
+        SourceParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct OperationParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (m_value.IsNull() || *m_value == L"") {
+                return;
+            }
+
+            m_data.m_operation = *m_value;
+        }
+
+        OperationParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct UriParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            // exception
+            DPL::String ignoreUri(L"file");
+
+            if (!m_value.IsNull() && *m_value == ignoreUri)
+            {
+                _D("exception : '%ls' scheme will be ignored.", (*m_value).c_str());
+                m_value = DPL::OptionalString::Null;
+            }
+
+            if (m_value.IsNull() || *m_value == L"") {
+                return;
+            }
+
+            DPL::String wildString(L"*/*");
+            if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
+                && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
+            {
+                m_data.m_uriList.insert(*m_value);
+            } else {
+                _D("Ignoring uri with name %ls", (*m_value).c_str());
+            }
+        }
+
+        UriParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct MimeParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (m_value.IsNull() || *m_value == L"") {
+                return;
+            }
+
+            DPL::String wildString(L"*/*");
+            if ((m_data.m_mimeList.find(wildString) ==
+                 m_data.m_mimeList.end())
+                && (m_data.m_mimeList.find(*m_value) ==
+                    m_data.m_mimeList.end()))
+            {
+                m_data.m_mimeList.insert(*m_value);
+            } else {
+                _D("Ignoring mime with name %ls", (*m_value).c_str());
+            }
+        }
+
+        MimeParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct DispositionParser : 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)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (m_value.IsNull() || *m_value == L"") {
+                return;
+            }
+
+            DPL::String windowString(L"window");
+            DPL::String inlineString(L"inline");
+
+            if (*m_value == L"window") {
+                m_data.m_disposition =
+                    ConfigParserData::AppControlInfo::Disposition::WINDOW;
+            } else if (*m_value == L"inline") {
+                m_data.m_disposition =
+                    ConfigParserData::AppControlInfo::Disposition::INLINE;
+            } else {
+                _D("Ignoring dispostion value %ls", (*m_value).c_str());
+            }
+        }
+
+        DispositionParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& name)
+    {
+        if (name == L"src") {
+            return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
+        } else if (name == L"operation") {
+            return DPL::MakeDelegate(this,
+                                     &AppControlParser::OnOperationElement);
+        } else if (name == L"uri") {
+            return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
+        } else if (name == L"mime") {
+            return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
+        } else if (name == L"disposition") {
+            return DPL::MakeDelegate(this,
+                                     &AppControlParser::OnDispositionElement);
+        } else {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        _W("namespace for app service = %ls", element.ns.c_str());
+        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_appControl.m_src == L"") {
+            ThrowMsg(Exception::ParseError, "service element must have src element");
+        }
+
+        if (m_appControl.m_operation == L"") {
+            ThrowMsg(Exception::ParseError, "service element must have operation element");
+        }
+
+        auto res = std::find(m_data.appControlList.begin(), m_data.appControlList.end(), m_appControl);
+        if(res != m_data.appControlList.end()) {
+            ThrowMsg(Exception::ParseError, "service element must be unique");
+        }
+
+#ifdef NFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY
+        // XXX This feature should be retained to Tizen 2.2 only.
+        // NFC exception handling which was requested from Tizen Device API team.
+
+        const DPL::String exceptionNfcOperation =
+                       L"http://tizen.org/appcontrol/operation/nfc/transaction";
+        const DPL::String exceptionNfcUri  = L"nfc://secure/aid/";
+        const DPL::String divertingNfcUri1 = L"nfc://secure/SIM1/aid/";
+        const DPL::String divertingNfcUri2 = L"nfc://secure/eSE/aid/";
+
+        if (m_appControl.m_operation == exceptionNfcOperation
+            && m_appControl.m_mimeList.empty()
+            && m_appControl.m_uriList.size() == 1
+            && (m_appControl.m_uriList.begin())->compare(0, exceptionNfcUri.length(), exceptionNfcUri) == 0)
+        {
+            DPL::String originalUri = *m_appControl.m_uriList.begin();
+            DPL::String newUri = originalUri;
+
+            newUri.replace(0, exceptionNfcUri.length(), divertingNfcUri1);
+            m_appControl.m_uriList.erase(m_appControl.m_uriList.begin());
+            m_appControl.m_uriList.insert(newUri);
+            m_data.appControlList.push_back(m_appControl);
+            _D("NFC exception : %ls -> %ls", originalUri.c_str(), newUri.c_str());
+
+            newUri = originalUri;
+            newUri.replace(0, exceptionNfcUri.length(), divertingNfcUri2);
+            m_appControl.m_uriList.erase(m_appControl.m_uriList.begin());
+            m_appControl.m_uriList.insert(newUri);
+            m_data.appControlList.push_back(m_appControl);
+            _D("NFC exception : %ls -> %ls", originalUri.c_str(), newUri.c_str());
+
+            return;
+        }
+#endif // NFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY
+
+        m_data.appControlList.push_back(m_appControl);
+    }
+
+    ElementParserPtr OnSourceElement()
+    {
+        return ElementParserPtr(new SourceParser(m_appControl));
+    }
+
+    ElementParserPtr OnOperationElement()
+    {
+        return ElementParserPtr(new OperationParser(m_appControl));
+    }
+
+    ElementParserPtr OnUriElement()
+    {
+        return ElementParserPtr(new UriParser(m_appControl));
+    }
+
+    ElementParserPtr OnMimeElement()
+    {
+        return ElementParserPtr(new MimeParser(m_appControl));
+    }
+
+    ElementParserPtr OnDispositionElement()
+    {
+        return ElementParserPtr(new DispositionParser(m_appControl));
+    }
+
+    AppControlParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_appControl(L"")
+    {}
+
+  private:
+    ConfigParserData& m_data;
+    ConfigParserData::AppControlInfo m_appControl;
+};
+
+class ApplicationParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        if (m_properNamespace) {
+            ThrowMsg(Exception::ParseError, "application element must be empty");
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"id") {
+                m_id = attribute.value;
+                NormalizeAndTrimSpaceString(m_id);
+            } else if (attribute.name == L"package") {
+                m_package = attribute.value;
+            } else if (attribute.name == L"required_version") {
+                m_version = attribute.value;
+                NormalizeString(m_version);
+            } else {
+                ThrowMsg(Exception::ParseError,
+                         "unknown attribute '" +
+                         DPL::ToUTF8String(attribute.name) +
+                         "' in application element");
+            }
+        }
+    }
+
+    virtual void Verify()
+    {
+        VerifyIdAndPackage();
+        VerifyVersion();
+    }
+
+    ApplicationParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_id(DPL::OptionalString::Null),
+        m_version(DPL::OptionalString::Null),
+        m_properNamespace(false)
+    {}
+
+    static const char* const REGEXP_ID;
+
+  private:
+    void VerifyIdAndPackage()
+    {
+        if (!m_package)
+        {
+            ThrowMsg(Exception::ParseError,
+                     "application element must have package attribute");
+        }
+        else
+        {
+            pcrecpp::RE re(REGEXP_PACKAGE);
+            if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid format of package attribute");
+            }
+        }
+
+        if (!m_id) {
+            ThrowMsg(Exception::ParseError,
+                     "application element must have id attribute");
+        }
+        else
+        {
+            std::string package;
+            pcrecpp::RE re(REGEXP_ID);
+            if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid format of id attribute");
+            }
+            if (package != DPL::ToUTF8String(*m_package))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid package prefix in id attribute");
+            }
+        }
+
+        m_data.tizenAppId = m_id;
+        m_data.tizenPkgId = m_package;
+    }
+
+    void VerifyVersion()
+    {
+        if (!m_version)
+        {
+            ThrowMsg(Exception::ParseError,
+                     "application element must have required_version attribute");
+        }
+        else
+        {
+            pcrecpp::RE re(REGEXP_VERSION);
+            if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid format of version attribute");
+            }
+        }
+
+        m_data.tizenMinVersionRequired = m_version;
+    }
+
+    static const char* const REGEXP_PACKAGE;
+    static const char* const REGEXP_VERSION;
+
+    ConfigParserData& m_data;
+    DPL::OptionalString m_id;
+    DPL::OptionalString m_package;
+    DPL::OptionalString m_version;
+    bool m_properNamespace;
+};
+
+const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
+const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
+const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)?";
+
+class SplashParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace)
+        {
+            if (attribute.name == L"src") {
+                if (attribute.value.size() > 0) {
+                    m_src = attribute.value;
+                }
+            }
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (m_src.IsNull())
+        {
+            _W("src attribute of splash element is mandatory - ignoring");
+            return;
+        }
+
+        m_data.splashImgSrc = m_src;
+    }
+
+    SplashParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+  private:
+    DPL::OptionalString m_src;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+class BackgroundParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (attribute.name == L"src") {
+            if (attribute.value.size() > 0) {
+                m_src = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& /*element*/)
+    {}
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (m_src.IsNull()) {
+            _W("src attribute of background element is mandatory - ignoring");
+            return;
+        }
+
+        m_data.backgroundPage = m_src;
+    }
+
+    explicit BackgroundParser(ConfigParserData& data) :
+        m_data(data)
+    {}
+
+  private:
+    DPL::OptionalString m_src;
+    ConfigParserData& m_data;
+};
+
+class PrivilegeParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+        _D("element");
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"name") {
+                m_feature.name = attribute.value;
+                m_privilege.name = attribute.value;
+            }
+        }
+    }
+
+    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 {
+                    _D("Ignoring feature with name %ls", m_feature.name.c_str());
+                }
+            }
+        }
+
+        LibIri::Wrapper iriPrivilege(
+            DPL::ToUTF8String(m_privilege.name).c_str());
+
+        if (m_privilege.name != L"") {
+            if (iriPrivilege.Validate()) {
+                if (m_data.privilegeList.find(m_privilege) ==
+                    m_data.privilegeList.end())
+                {
+                    m_data.privilegeList.insert(m_privilege);
+                } else {
+                    _D("Ignoring privilege with name %ls", m_privilege.name.c_str());
+                }
+            }
+        }
+    }
+
+    PrivilegeParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_feature(L""),
+        m_privilege(L""),
+        m_properNamespace(false)
+    {}
+
+  private:
+    ConfigParserData& m_data;
+    ConfigParserData::Feature m_feature;
+    ConfigParserData::Privilege m_privilege;
+    bool m_properNamespace;
+};
+
+class CategoryParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (attribute.name == L"name") {
+            if (attribute.value.size() > 0) {
+                m_name = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& /*element*/)
+    {}
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (m_name.IsNull()) {
+            _W("name attribute of category element is mandatory - ignoring");
+            return;
+        }
+
+        if (m_data.categoryList.find(*m_name) ==
+            m_data.categoryList.end())
+        {
+            m_data.categoryList.insert(*m_name);
+        }
+    }
+
+    explicit CategoryParser(ConfigParserData& data) :
+        m_data(data)
+    {}
+
+  private:
+    DPL::OptionalString m_name;
+    ConfigParserData& m_data;
+};
+
+class AppWidgetParser : public ElementParser
+{
+  public:
+
+    struct BoxLabelParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (m_properNamespace) {
+                 m_lang = attribute.lang;
+            }
+        }
+        virtual void Accept(const Element& element)
+        {
+            if (element.ns ==
+                ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                m_properNamespace = true;
+            }
+        }
+
+        virtual void Accept(const Text& text)
+        {
+            if (m_properNamespace) {
+                m_label = text.value;
+            }
+        }
+
+        virtual void Verify()
+        {
+            std::pair<DPL::String, DPL::String> boxLabel;
+            if (m_label.empty()) {
+                _W("box-label element is empty");
+                boxLabel.first = DPL::FromUTF8String("");
+                boxLabel.second = DPL::FromUTF8String("");
+                m_data.m_label.push_back(boxLabel);
+            }
+            else {
+                boxLabel.first = m_lang;
+                boxLabel.second = m_label;
+                m_data.m_label.push_back(boxLabel);
+            }
+        }
+
+        BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        DPL::String m_lang;
+        DPL::String m_label;
+        bool m_properNamespace;
+        ConfigParserData::LiveboxInfo& m_data;
+    };
+
+    struct BoxIconParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (m_properNamespace) {
+                if (attribute.name == L"src") {
+                    m_icon = attribute.value;
+                }
+            }
+        }
+
+        virtual void Accept(const Element& element)
+        {
+            if (element.ns ==
+                ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                m_properNamespace = true;
+            }
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Verify()
+        {
+            if (m_icon.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "src attribute of box-icon element is mandatory - ignoring");
+            }
+            if (!m_data.m_icon.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "<tizen:box-icon /> element should occur as 0 or 1 time");
+            }
+            m_data.m_icon = m_icon;
+        }
+
+        explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        DPL::String m_icon;
+        bool m_properNamespace;
+        ConfigParserData::LiveboxInfo& m_data;
+    };
+
+    struct BoxContentParser : public ElementParser
+    {
+        struct BoxSizeParser : public ElementParser
+        {
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                                const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const XmlAttribute& attribute)
+            {
+                if (m_properNamespace) {
+                    if (attribute.name == L"preview") {
+                        m_preview = attribute.value;
+                    }
+                    if (attribute.name == L"use-decoration") {
+                        m_useDecoration = attribute.value;
+                    }
+                }
+            }
+
+            virtual void Accept(const Element& element)
+            {
+                if (element.ns ==
+                    ConfigurationNamespace::TizenWebAppNamespaceName)
+                {
+                    m_properNamespace = true;
+                }
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (m_properNamespace) {
+                    m_size = text.value;
+                }
+            }
+
+            virtual void Verify()
+            {
+                if(m_size.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "size is mandatory - ignoring");
+                }
+
+                ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
+                boxSizeInfo.m_size = m_size;
+                boxSizeInfo.m_preview = m_preview;
+                boxSizeInfo.m_useDecoration = m_useDecoration;
+                m_data.m_boxSize.push_back(boxSizeInfo);
+            }
+
+            explicit BoxSizeParser(
+                ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+            {}
+
+          private:
+            DPL::String m_size;
+            DPL::String m_preview;
+            DPL::String m_useDecoration;
+            bool m_properNamespace;
+            ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
+        };
+
+        struct PdParser : public ElementParser
+        {
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                                const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const XmlAttribute& attribute)
+            {
+                if (m_properNamespace) {
+                    if (attribute.name == L"src") {
+                        m_src = attribute.value;
+                    } else if (attribute.name == L"width") {
+                        m_width = attribute.value;
+                    } else if (attribute.name == L"height") {
+                        m_height = attribute.value;
+                    } else if (attribute.name == L"fast-open") {
+                        m_fastOpen= attribute.value;
+                    }
+                }
+            }
+
+            virtual void Accept(const Element& element)
+            {
+                if (element.ns ==
+                    ConfigurationNamespace::TizenWebAppNamespaceName)
+                {
+                    m_properNamespace = true;
+                }
+            }
+
+            virtual void Accept(const Text& /*text*/)
+            {}
+
+            virtual void Verify()
+            {
+                if (m_src.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "src attribute of pd element is mandatory - ignoring");
+                }
+
+                if (m_width.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "width attribute of pd element is mandatory - ignoring");
+                }
+
+                if (m_height.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "height attribute of pd element is mandatory - ignoring");
+                }
+
+                if (ConvertToInt(m_width).IsNull()) {
+                    ThrowMsg(Exception::ParseError,
+                        "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
+                }
+
+
+                DPL::OptionalInt height = ConvertToInt(m_height);
+
+                if (height.IsNull()) {
+                    ThrowMsg(Exception::ParseError,
+                        "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
+                }
+
+                if (*height < 1) {
+                    m_height = L"1";
+                    _D("height attribute of pd element shouldn't be less than 1. Changed to 1 from %d", *height);
+                } else if (*height > 380){
+                    m_height = L"380";
+                    _D("height attribute of pd element shouldn't be greater than 380. Changed to 380 from %d", *height);
+                }
+
+                m_data.m_pdSrc = m_src;
+                m_data.m_pdWidth = m_width;
+                m_data.m_pdHeight = m_height;
+                m_data.m_pdFastOpen = m_fastOpen;
+            }
+
+            explicit PdParser(
+                ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+            {}
+
+          private:
+            DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
+            {
+                char * endptr;
+                std::string tempStr = DPL::ToUTF8String(intAsString);
+                const char * intAsString_c = tempStr.c_str();
+                errno = 0;
+                long int intAsString_i = strtol(intAsString_c, &endptr, 10);
+
+                if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
+                        || intAsString_i > INT_MAX || intAsString_i < INT_MIN
+                        || *endptr != '\0') {
+                    return DPL::OptionalInt::Null;
+                }
+
+                return static_cast<int>(intAsString_i);
+            }
+
+            DPL::String m_src;
+            DPL::String m_width;
+            DPL::String m_height;
+            DPL::String m_fastOpen;
+
+            bool m_properNamespace;
+            ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
+        };
+
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& name)
+        {
+            if (name == L"box-size") {
+                return DPL::MakeDelegate(
+                           this,
+                           &AppWidgetParser::BoxContentParser::
+                               OnBoxSizeElement);
+            } else if (name == L"pd") {
+                return DPL::MakeDelegate(
+                           this,
+                           &AppWidgetParser::BoxContentParser::
+                               OnPdElement);
+            } else {
+                ThrowMsg(Exception::ParseError,
+                         "No element parser for name: " << name);
+            }
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (m_properNamespace) {
+                if (attribute.name == L"src") {
+                    m_box.m_boxSrc = attribute.value;
+                }
+                if (attribute.name == L"mouse-event") {
+                    m_box.m_boxMouseEvent = attribute.value;
+                }
+                if (attribute.name == L"touch-effect") {
+                    m_box.m_boxTouchEffect = attribute.value;
+                }
+            }
+        }
+
+        virtual void Accept(const Element& element)
+        {
+            if (element.ns ==
+                ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                m_properNamespace = true;
+            }
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Verify()
+        {
+            if (m_box.m_boxSrc.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "src attribute of box-content element is mandatory - ignoring");
+            }
+
+            if (!m_box.m_boxMouseEvent.empty() &&
+                    CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent))
+            {
+                ThrowMsg(Exception::ParseError,
+                    "mouse-event attribute of box-content element should be true or false - ignoring");
+            }
+
+            if (!m_box.m_boxTouchEffect.empty() &&
+                    CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect))
+            {
+                ThrowMsg(Exception::ParseError,
+                    "touch-effect attribute of box-content element should be true or false - ignoring");
+            }
+
+            if (m_box.m_boxMouseEvent.empty()) {
+                m_box.m_boxMouseEvent = L"false";
+            }
+
+            if (m_box.m_boxTouchEffect.empty()) {
+                m_box.m_boxTouchEffect = L"true";
+            }
+
+            if (m_box.m_boxSize.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "box-size element of box-content element not found - ignoring");
+            }
+
+            m_data.m_boxInfo = m_box;
+        }
+
+        explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+        ElementParserPtr OnBoxSizeElement()
+        {
+            return ElementParserPtr(new BoxSizeParser(m_box));
+        }
+
+        ElementParserPtr OnPdElement()
+        {
+            return ElementParserPtr(new PdParser(m_box));
+        }
+
+      private:
+        bool m_properNamespace;
+        ConfigParserData::LiveboxInfo& m_data;
+        ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& name)
+    {
+        if (name == L"box-label") {
+            return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
+        } else if (name == L"box-icon") {
+            return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
+        } else if (name == L"box-content") {
+            return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
+        } else {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"id") {
+                m_liveboxId = attribute.value;
+            } else if (attribute.name == L"primary") {
+                m_primary = attribute.value;
+            } else if (attribute.name == L"auto-launch") {
+                m_autoLaunch = attribute.value;
+            } else if (attribute.name == L"update-period") {
+                m_updatePeriod = attribute.value;
+            } else if (attribute.name == L"type") {
+                m_type = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (m_liveboxId.empty()) {
+            ThrowMsg(Exception::ParseError,
+                 "app-widget element must have id attribute");
+        }
+        else
+        {
+            pcrecpp::RE re(REGEXP_ID_STRING.c_str());
+            if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
+            {
+                ThrowMsg(Exception::ParseError,
+                     "invalid format of app-widget id attribute");
+            }
+        }
+
+        if (m_primary.empty())
+        {
+            ThrowMsg(Exception::ParseError,
+                 "app-widget element must have primary attribute");
+        } else if (CheckIfNotTrueNorFalse(m_primary))
+        {
+            ThrowMsg(Exception::ParseError,
+                "auto-launch attribute of app-widget element should be true or false - ignoring");
+        }
+
+        if (!m_autoLaunch.empty() &&
+                CheckIfNotTrueNorFalse(m_autoLaunch))
+        {
+            ThrowMsg(Exception::ParseError,
+                "auto-launch attribute of app-widget element should be true or false - ignoring");
+        }
+
+        if (!m_updatePeriod.empty())
+        {
+            char * endptr;
+            errno = 0;
+            std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
+
+            //set standard locale to fix decimal point mark - '.'
+            std::string currentLocale = setlocale(LC_NUMERIC, NULL);
+            if (NULL == setlocale(LC_NUMERIC, "C"))
+                _W("Failed to change locale to \"C\"");
+            double updatePeriod = strtod(tempStr.c_str(), &endptr);
+
+            //go back to previous locale
+            if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
+                _W("Failed to set previous locale");
+
+            if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
+                    || *endptr != '\0') {
+                ThrowMsg(Exception::ParseError,
+                    "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
+            } else if (updatePeriod < 1800.0) {
+                _D("update-period attribute of app-widget element shouldn't be less than 1800.0 - changed to 1800 from value: %ls", m_updatePeriod.c_str());
+                m_updatePeriod = L"1800.0";
+            }
+        }
+
+        if (m_autoLaunch.empty()) {
+            m_autoLaunch = L"false";
+        }
+
+        if(m_livebox.m_label.empty()) {
+            ThrowMsg(Exception::ParseError,
+                "box-label element of app-widget element not found - ignoring");
+        }
+
+        if(!m_boxContentFound) {
+            ThrowMsg(Exception::ParseError,
+                "box-content element of app-widget element not found - ignoring");
+        }
+
+        m_livebox.m_liveboxId = m_liveboxId;
+        m_livebox.m_primary = m_primary;
+        m_livebox.m_autoLaunch = m_autoLaunch;
+        m_livebox.m_updatePeriod = m_updatePeriod;
+        m_livebox.m_type = m_type;
+
+        m_data.m_livebox.push_back(m_livebox);
+    }
+
+    explicit AppWidgetParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false),
+        m_boxContentFound(false)
+    {
+        m_livebox = ConfigParserData::LiveboxInfo();
+    }
+
+    ElementParserPtr OnBoxLabelElement()
+    {
+
+        return ElementParserPtr(new BoxLabelParser(m_livebox));
+    }
+
+    ElementParserPtr OnBoxIconElement()
+    {
+        return ElementParserPtr(new BoxIconParser(m_livebox));
+    }
+
+    ElementParserPtr OnBoxContentElement()
+    {
+        m_boxContentFound = true;
+        return ElementParserPtr(new BoxContentParser(m_livebox));
+    }
+
+  private:
+    static std::string REGEXP_ID_STRING;
+    ConfigParserData& m_data;
+    ConfigParserData::LiveboxInfo m_livebox;
+    DPL::String m_liveboxId;
+    DPL::String m_primary;
+    DPL::String m_autoLaunch;
+    DPL::String m_updatePeriod;
+    DPL::String m_type;
+    bool m_properNamespace;
+    bool m_boxContentFound;
+
+    static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
+    {
+        return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
+    }
+};
+
+std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
+
+class AllowNavigationParser : public ElementParser
+{
+  public:
+    AllowNavigationParser(ConfigParserData& data) :
+      ElementParser(),
+      m_data(data),
+      m_properNamespace(false)
+    {}
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& text)
+    {
+        if (m_properNamespace)
+        {
+            m_origin = text.value;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {
+    }
+
+    virtual void Verify()
+    {
+        if (m_data.allowNavigationEncountered || !m_properNamespace)
+        {
+            return;
+        }
+        m_data.allowNavigationEncountered = true;
+
+        if (m_origin.IsNull()) {
+            _W("data is empty");
+            return;
+        }
+
+        char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
+        char* ptr = strtok(data," ");
+        while (ptr != NULL) {
+            std::string origin = ptr;
+            ptr = strtok(NULL," ");
+            if(origin == "*") {
+                ConfigParserData::AllowNavigationInfo info(L"*", L"*");
+                m_data.allowNavigationInfoList.push_back(info);
+                continue;
+            }
+
+            std::unique_ptr<iri_t, decltype(&iri_destroy)> iri(iri_parse(origin.c_str()), iri_destroy);
+            if (!iri->host || strlen(iri->host) == 0) {
+                // input origin should has schem and host
+                // in case of file scheme path is filled
+                // "http://"
+                _W("input origin isn't verified");
+                continue;
+            }
+            DPL::String scheme = L"*";
+            if (iri->scheme && strlen(iri->scheme) != 0) {
+                scheme = DPL::FromUTF8String(iri->scheme);
+            }
+            ConfigParserData::AllowNavigationInfo info(
+                scheme,
+                DPL::FromUTF8String(iri->host));
+            m_data.allowNavigationInfoList.push_back(info);
+        }
+        free(data);
+    }
+
+  private:
+    DPL::OptionalString m_origin;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+class CspParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    CspParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {}
+
+    virtual void Accept(const Text& text)
+    {
+        if (m_properNamespace) {
+            m_policy = text.value;
+        }
+    }
+
+    virtual void Verify()
+    {
+        if (!m_policy.IsNull()) {
+            m_data.cspPolicy = *m_policy;
+        }
+    }
+
+  private:
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+    DPL::OptionalString m_policy;
+};
+
+class CspReportOnlyParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    CspReportOnlyParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {}
+
+    virtual void Accept(const Text& text)
+    {
+        if (m_properNamespace) {
+            m_policy = text.value;
+        }
+    }
+
+    virtual void Verify()
+    {
+        if (!m_policy.IsNull()) {
+            m_data.cspPolicyReportOnly = *m_policy;
+        }
+    }
+
+  private:
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+    DPL::OptionalString m_policy;
+};
+
+class AccountParser : public ElementParser
+{
+  public:
+      struct IconParser : public ElementParser
+    {
+        public:
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                    const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (text.value == L"") {
+                    return;
+                }
+                m_value = text.value;
+            }
+
+            virtual void Accept(const Element& /*element*/)
+            {}
+
+            virtual void Accept(const XmlAttribute& attribute)
+            {
+                if (attribute.name == L"section") {
+                    if (attribute.value == L"Account") {
+                        m_type = ConfigParserData::IconSectionType::DefaultIcon;
+                    } else if (attribute.value == L"AccountSmall") {
+                        m_type = ConfigParserData::IconSectionType::SmallIcon;
+                    }
+                }
+            }
+
+            virtual void Verify()
+            {
+                if (m_value.IsNull() || *m_value == L"") {
+                    return;
+                }
+
+                std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
+                icon.first = m_type;
+                icon.second = *m_value;
+
+                m_data.m_iconSet.insert(icon);
+            }
+
+            IconParser(ConfigParserData::AccountProvider& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_type(ConfigParserData::DefaultIcon),
+                m_data(data)
+        {}
+
+        private:
+            bool m_properNamespace;
+            ConfigParserData::IconSectionType m_type;
+            ConfigParserData::AccountProvider& m_data;
+            DPL::OptionalString m_value;
+    };
+
+      struct DisplayNameParser : public ElementParser
+    {
+        public:
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                    const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (text.value == L"") {
+                    return;
+                }
+                m_value = text.value;
+            }
+
+            virtual void Accept(const Element& element)
+            {
+                m_lang = element.lang;
+                m_value= L"";
+            }
+
+            virtual void Accept(const XmlAttribute& /*attribute*/)
+            {}
+
+            virtual void Verify()
+            {
+                if (m_value.IsNull() || *m_value == L"") {
+                    return;
+                }
+
+                std::pair<DPL::String, DPL::String> name;
+                name.first = *m_lang;
+                name.second = *m_value;
+
+                m_data.m_displayNameSet.insert(name);
+            }
+
+            DisplayNameParser(ConfigParserData::AccountProvider& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+        {}
+
+        private:
+            bool m_properNamespace;
+            DPL::OptionalString m_lang;
+            DPL::OptionalString m_value;
+            ConfigParserData::AccountProvider& m_data;
+    };
+
+      struct CapabilityParser : public ElementParser
+    {
+        public:
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                    const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (text.value == L"") {
+                    return;
+                }
+                m_value = text.value;
+            }
+
+            virtual void Accept(const Element& /*element*/)
+            {}
+
+            virtual void Accept(const XmlAttribute& /*attribute*/)
+            {}
+
+            virtual void Verify()
+            {
+                if (m_value.IsNull() || *m_value == L"") {
+                    return;
+                }
+                m_data.m_capabilityList.push_back(*m_value);
+            }
+
+            CapabilityParser(ConfigParserData::AccountProvider& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+        {}
+
+        private:
+            bool m_properNamespace;
+            DPL::OptionalString m_value;
+            ConfigParserData::AccountProvider& m_data;
+    };
+      virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+              const DPL::String& name)
+      {
+          if (name == L"icon") {
+              return DPL::MakeDelegate(this, &AccountParser::OnIconElement);
+          } else if (name == L"display-name") {
+              return DPL::MakeDelegate(this,
+                      &AccountParser::OnDisplayNameElement);
+          } else if (name == L"capability") {
+              return DPL::MakeDelegate(this, &AccountParser::OnCapabilityElement);
+          } else {
+              return &IgnoringParser::Create; //ignore unknown according to w3c
+          }
+      }
+
+      virtual void Accept(const Text& /*text*/)
+      {}
+
+      virtual void Accept(const Element& /*element*/)
+      {}
+
+      virtual void Accept(const XmlAttribute& attribute)
+      {
+          if (attribute.name == L"multiple-account-support") {
+              if (attribute.value == L"true") {
+                  m_account.m_multiAccountSupport = true;
+              }
+          }
+      }
+
+      virtual void Verify()
+      {
+      }
+
+      ElementParserPtr OnIconElement()
+      {
+          return ElementParserPtr(new IconParser(m_account));
+      }
+
+      ElementParserPtr OnDisplayNameElement()
+      {
+          return ElementParserPtr(new DisplayNameParser(m_account));
+      }
+
+      ElementParserPtr OnCapabilityElement()
+      {
+          return ElementParserPtr(new CapabilityParser(m_account));
+      }
+
+      AccountParser(ConfigParserData& data) :
+          ElementParser(),
+          m_properNamespace(false),
+          m_multiSupport(false),
+          m_data(data),
+          m_account(data.accountProvider)
+    {
+    }
+
+  private:
+      bool m_properNamespace;
+      bool m_multiSupport;
+      ConfigParserData& m_data;
+      ConfigParserData::AccountProvider& m_account;
+};
+
+class MetadataParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"key") {
+                m_key = attribute.value;
+            } else if (attribute.name == L"value") {
+                m_value = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        ThrowMsg(Exception::ParseError, "param element must be empty");
+    }
+
+    virtual void Verify()
+    {
+        if (m_key.IsNull()) {
+            _W("metadata element must have key attribute");
+            return;
+        }
+        NormalizeString(m_key);
+        NormalizeString(m_value);
+        ConfigParserData::Metadata metaData(m_key, m_value);
+        FOREACH(it, m_data.metadataList) {
+            if (!DPL::StringCompare(*it->key, *m_key)) {
+                _E("Key isn't unique");
+                return;
+            }
+        }
+        m_data.metadataList.push_back(metaData);
+    }
+
+    MetadataParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+  private:
+    DPL::OptionalString m_key;
+    DPL::OptionalString m_value;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+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; //ignore unknown according to w3c
+    }
+}
+
+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"preference"] =
+        DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
+    m_map[L"setting"] =
+        DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
+    m_map[L"application"] = DPL::MakeDelegate(
+            this,
+            &WidgetParser::
+                OnApplicationElement);
+    m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
+    m_map[L"background"] = DPL::MakeDelegate(this,
+                                             &WidgetParser::OnBackgroundElement);
+    m_map[L"privilege"] = DPL::MakeDelegate(this,
+                                            &WidgetParser::OnPrivilegeElement);
+    m_map[L"app-control"] = DPL::MakeDelegate(
+            this,
+            &WidgetParser::
+                OnAppControlElement);
+    m_map[L"category"] = DPL::MakeDelegate(this,
+                                           &WidgetParser::OnCategoryElement);
+    m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
+#ifdef CSP_ENABLED
+    m_map[L"content-security-policy"] = DPL::MakeDelegate(
+            this,
+            &WidgetParser::
+                OnCspElement);
+    m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
+            this,
+            &WidgetParser::
+                OnCspReportOnlyElement);
+#endif
+#ifdef ALLOW_NAVIGATION_ENABLED
+    m_map[L"allow-navigation"] =
+        DPL::MakeDelegate(this, &WidgetParser::OnAllowNavigationElement);
+#endif
+    m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
+    m_map[L"metadata"] = DPL::MakeDelegate(this, &WidgetParser::OnMetadataElement);
+}
+
+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::OnPreferenceElement()
+{
+    return ElementParserPtr(new PreferenceParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnSettingElement()
+{
+    return ElementParserPtr(new SettingParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnApplicationElement()
+{
+    return ElementParserPtr(new ApplicationParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnSplashElement()
+{
+    return ElementParserPtr(new SplashParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnBackgroundElement()
+{
+    return ElementParserPtr(new BackgroundParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnPrivilegeElement()
+{
+    return ElementParserPtr(new PrivilegeParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAppControlElement()
+{
+    return ElementParserPtr(new AppControlParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnCategoryElement()
+{
+    return ElementParserPtr(new CategoryParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAppWidgetElement()
+{
+    return ElementParserPtr(new AppWidgetParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnCspElement()
+{
+    return ElementParserPtr(new CspParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnCspReportOnlyElement()
+{
+    return ElementParserPtr(new CspReportOnlyParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAllowNavigationElement()
+{
+    return ElementParserPtr(new AllowNavigationParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAccountElement()
+{
+    return ElementParserPtr(new AccountParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnMetadataElement()
+{
+    return ElementParserPtr(new MetadataParser(m_data));
+}
+
+void WidgetParser::Accept(const Element& element)
+{
+    if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
+        element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
+    {
+        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 {
+            _W("Widget id validation failed: %ls", attribute.value.c_str());
+        }
+    } else if (attribute.name == L"version") {
+        m_version = attribute.value;
+        NormalizeString(m_version);
+    } else if (attribute.name == L"min-version") {
+        _D("min-version attribute was found. Value: %ls", attribute.value.c_str());
+        m_minVersion = attribute.value;
+        NormalizeString(m_minVersion);
+        m_data.minVersionRequired = m_minVersion;
+    } 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 (isdigit(c)) {
+                int val = 0;
+                for (size_t i = 0; i < v.size(); ++i) {
+                    c = v.c_str()[i];
+                    if (isdigit(c)) {
+                        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);
+            std::string dl = DPL::ToUTF8String(*m_defaultlocale);
+
+            if (!LanguageSubtagRstTreeSingleton::Instance().
+                    ValidateLanguageTag(dl)) {
+                _W("Language tag: %s is not valid", dl.c_str());
+                m_defaultlocale = DPL::OptionalString::Null;
+            } else {
+                _D("Default locale found %s", dl.c_str());
+            }
+        } else {
+            _W("Ignoring subsequent default locale");
+        }
+        //Any other value consider as a namespace definition
+    } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
+        _D("Namespace domain: %ls", attribute.name.c_str());
+        _D("Namespace value: %ls", attribute.value.c_str());
+        m_nameSpaces[attribute.name] = attribute.value;
+    } else {
+        _E("Unknown attirbute: namespace=%ls, name=%ls, value=%ls",
+            attribute.ns.c_str(), attribute.name.c_str(), attribute.value.c_str());
+    }
+}
+
+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->second);
+    }
+}
+
diff --git a/src_mobile/configuration_parser/widget_parser.h b/src_mobile/configuration_parser/widget_parser.h
new file mode 100644 (file)
index 0000000..f59b725
--- /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 <map>
+#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 TizenWebAppNamespaceName =
+    L"http://tizen.org/ns/widgets";
+}
+
+namespace PluginsPrefix {
+const char * const W3CPluginsPrefix = "http://www.w3.org/";
+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 OnPreferenceElement();
+    ElementParserPtr OnAccessElement();
+    ElementParserPtr OnSettingElement();
+    ElementParserPtr OnApplicationElement();
+    ElementParserPtr OnSplashElement();
+    ElementParserPtr OnBackgroundElement();
+    ElementParserPtr OnPrivilegeElement();
+    ElementParserPtr OnAppControlElement();
+    ElementParserPtr OnCategoryElement();
+    ElementParserPtr OnAppWidgetElement();
+    ElementParserPtr OnCspElement();
+    ElementParserPtr OnCspReportOnlyElement();
+    ElementParserPtr OnAllowNavigationElement();
+    ElementParserPtr OnAccountElement();
+    ElementParserPtr OnMetadataElement();
+
+    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;
+    DPL::Optional<DPL::String> m_minVersion;
+    std::list<DPL::String> m_windowModes;
+    DPL::Optional<DPL::String> m_defaultlocale;
+    std::map<DPL::String, DPL::String> m_nameSpaces;
+};
+
+struct IconParser;
+struct ContentParser;
+
+#endif // WIDGET_PARSER_H_
diff --git a/src_mobile/jobs/job.cpp b/src_mobile/jobs/job.cpp
new file mode 100644 (file)
index 0000000..ec2bb7f
--- /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 <job.h>
+#include <installer_controller.h>
+
+namespace Jobs {
+Job::Job(InstallationType installType) :
+    m_handle(0),
+    m_installationType(installType),
+    m_abortStarted(false),
+    m_paused(false)
+{}
+
+InstallationType Job::GetInstallationType() const
+{
+    return m_installationType;
+}
+
+bool Job::GetAbortStarted() const
+{
+    return m_abortStarted;
+}
+
+void Job::SetAbortStarted(bool flag)
+{
+    m_abortStarted = 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(Logic::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::SendProgressIconPath(const std::string &/*path*/)
+{}
+
+void Job::SaveExceptionData(const Jobs::JobExceptionBase&)
+{}
+} //namespace Jobs
diff --git a/src_mobile/jobs/job.h b/src_mobile/jobs/job.h
new file mode 100644 (file)
index 0000000..3963fc6
--- /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.
+ */
+#ifndef INSTALLER_MODEL_H
+#define INSTALLER_MODEL_H
+
+#include <dpl/mutable_task_list.h>
+
+#include <job_types.h>
+
+namespace Jobs {
+class JobExceptionBase;
+
+typedef int JobHandle;
+
+class Job :
+    public DPL::MutableTaskList
+{
+  public:
+    Job(InstallationType installType);
+
+    InstallationType GetInstallationType() const;
+
+    // Undo
+    void SetAbortStarted(bool flag);
+    bool GetAbortStarted() 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 SendProgressIconPath(const std::string &path);
+
+    virtual void SaveExceptionData(const Jobs::JobExceptionBase&);
+
+  private:
+    JobHandle m_handle;
+    InstallationType m_installationType;
+    bool m_abortStarted;
+    bool m_paused;
+};
+} //namespace Jobs
+
+#endif // INSTALLER_MODEL_H
diff --git a/src_mobile/jobs/job_base.h b/src_mobile/jobs/job_base.h
new file mode 100644 (file)
index 0000000..edcf0f5
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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)) /
+             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;
+    }
+
+  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_mobile/jobs/job_exception_base.h b/src_mobile/jobs/job_exception_base.h
new file mode 100644 (file)
index 0000000..4d35420
--- /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.
+ */
+/**
+ * @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;                                                         \
+    };
+
+#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;                                                  \
+        }                                                                    \
+    };
+
+namespace Jobs {
+DECLARE_JOB_EXCEPTION_BASE(DPL::Exception, JobExceptionBase, 0)
+}
+
+#endif /* SRC_INSTALLER_CORE_JOBS_JOB_EXCEPTION_BASE_H_ */
diff --git a/src_mobile/jobs/job_exception_error.h b/src_mobile/jobs/job_exception_error.h
new file mode 100644 (file)
index 0000000..1caba99
--- /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        job_exception_error.h
+ * @author      Soyoung Kim (sy037.kim@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 JOB_EXCEPTION_ERROR_H
+#define JOB_EXCEPTION_ERROR_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+namespace Jobs {
+namespace Exceptions {
+enum Type
+{
+    Success = 0,                         ///< Success
+
+    /* pkgmgr error */
+    ErrorPackageNotFound,                       ///<
+    ErrorPackageInvalid,                        ///< invalid widget package
+    ErrorPackageLowerVersion,                   ///< given version is lower
+    ErrorPackageExecutableNotFound,
+
+    ErrorManifestNotFound = 11,                 ///<
+    ErrorManifestInvalid,                       ///<
+    ErrorConfigNotFound,                        ///< couldn't find config.xml
+    ErrorConfigInvalid,                         ///< invalid config.xml
+
+    ErrorSignatureNotFound = 21,                ///< signature file not exist.
+    ErrorSignatureInvalid,                      ///< invalid signature file
+    ErrorSignatureVerificationFailed,           ///< failure in verificate
+                                                ///< signature
+    ErrorRootCertificateNotFound = 31,          ///< couldn't find root
+    ErrorCertificationInvaid,                   ///< invalid certification
+    ErrorCertificateChainVerificationFailed,    ///< failure in verificate
+    ErrorCertificateExpired,                    ///< expire cerification.
+
+    ErrorInvalidPrivilege = 41,                 ///< invalid privilege.
+    ErrorPrivilegeLevelViolation,
+
+    ErrorMenuIconNotFound = 51,                 ///<
+
+    ErrorFatalError = 61,                       ///< failure in db operation
+    ErrorOutOfStorage,                          ///< failure in shortage of memory
+    ErrorOutOfMemory,                           ///< failure in shortage of RAM
+    ErrorArgumentInvalid,
+
+    /* wrt-installer error */
+    /* 121-140 : reserved for Web installer */
+    ErrorPackageAlreadyInstalled = 121,     ///< package already in target.
+    ErrorAceCheckFailed,                    ///< failure in ace check.
+    ErrorManifestCreateFailed,              ///< failure in creating manifest
+    ErrorEncryptionFailed,                  ///< failure in encryption resource
+    ErrorInstallOspServcie,                 ///< Failure in installing osp service
+    ErrorPluginInstallationFailed,          ///< failure in plugin installation
+    ErrorWidgetUninstallationFailed,        ///< failure in uninstallation
+    ErrorNotSupportRDSUpdate,               ///< failure in rds update
+
+    ErrorUnknown = 140,                     ///< do not use this error code.
+};
+}
+}
+
+#endif /* JOB_EXCEPTION_ERROR_H */
diff --git a/src_mobile/jobs/job_types.h b/src_mobile/jobs/job_types.h
new file mode 100644 (file)
index 0000000..5f845bf
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013 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_types.h
+ * @author  Tomasz Iwanek ()
+ */
+#ifndef JOB_TYPES_H
+#define JOB_TYPES_H
+
+namespace Jobs {
+/**
+ * @brief Defines installation and uninstallation type.
+ */
+enum InstallationType
+{
+    UnknownInstallation,  ///< defines installation of yet unknown type
+    NewInstallation,      ///< defines install process
+    UpdateInstallation,   ///< defines update installation
+    Uninstallation,       ///< defines uninstall process
+    PluginInstallation    ///< defines plugin installation process
+};
+
+}
+
+#endif // JOB_TYPES_H
diff --git a/src_mobile/jobs/plugin_install/job_plugin_install.cpp b/src_mobile/jobs/plugin_install/job_plugin_install.cpp
new file mode 100644 (file)
index 0000000..2bcd9de
--- /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.
+ */
+/**
+ * @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 "plugin_objects.h"
+#include <wrt_common_types.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace PluginInstall {
+JobPluginInstall::JobPluginInstall(PluginPath const &pluginPath,
+                                   const PluginInstallerStruct &installerStruct)
+    :
+    Job(PluginInstallation),
+    JobContextBase<PluginInstallerStruct>(installerStruct),
+    m_exceptionCaught(Jobs::Exceptions::Success)
+{
+    //
+    // 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) {
+        _D("Call Plugin install progressCallback");
+        GetInstallerStruct().progressCallback(GetInstallerStruct().userParam,
+                                              GetProgressPercent(),
+                                              GetProgressDescription());
+    }
+}
+
+void JobPluginInstall::SendFinishedSuccess()
+{
+    PluginHandle handle = getNewPluginHandle();
+
+    if (handle != Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE &&
+        isReadyToInstall())
+    {
+        _D("Call Plugin install success finishedCallback");
+        GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                              Jobs::Exceptions::Success);
+    } else {
+        _D("Call Plugin install waiting finishedCallback");
+        GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                              Jobs::Exceptions::ErrorPluginInstallationFailed);
+
+        _D("Installation: %s NOT possible", getFilePath().c_str());
+    }
+}
+
+void JobPluginInstall::SendFinishedFailure()
+{
+    _E("Error in plugin installation step: %d", m_exceptionCaught);
+    _E("Message: %s", m_exceptionMessage.c_str());
+
+    _D("Call Plugin install failure finishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          m_exceptionCaught);
+}
+
+void JobPluginInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
+{
+    m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
+    m_exceptionMessage = e.GetMessage();
+}
+} //namespace Jobs
+} //namespace PluginInstall
diff --git a/src_mobile/jobs/plugin_install/job_plugin_install.h b/src_mobile/jobs/plugin_install/job_plugin_install.h
new file mode 100644 (file)
index 0000000..a8d3386
--- /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    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(PluginPath const &pluginPath,
+                     const PluginInstallerStruct &installerStruct);
+
+    WrtDB::DbPluginHandle getNewPluginHandle() const
+    {
+        return m_context.pluginHandle;
+    }
+    std::string getFilePath() const
+    {
+        return m_context.pluginFilePath.Fullpath();
+    }
+    bool isReadyToInstall() const
+    {
+        return m_context.installationCompleted;
+    }
+
+    void SendProgress();
+    void SendFinishedSuccess();
+    void SendFinishedFailure();
+    void SaveExceptionData(const Jobs::JobExceptionBase &e);
+
+  private:
+   PluginInstallerContext m_context;
+
+    //TODO move it to base class of all jobs
+    //maybe separate JobBase class for this?
+    Jobs::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_mobile/jobs/plugin_install/plugin_install_task.cpp b/src_mobile/jobs/plugin_install/plugin_install_task.cpp
new file mode 100644 (file)
index 0000000..5f42730
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * 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/foreach.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"
+#include <wrt_plugin_export.h>
+#include <plugin_path.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+#define SET_PLUGIN_INSTALL_PROGRESS(step, desc)              \
+    m_context->installerTask->UpdateProgress(               \
+        PluginInstallerContext::step, desc);
+
+#define DISABLE_IF_PLUGIN_WITHOUT_LIB()        \
+    if (m_pluginInfo.m_libraryName.empty()) \
+    {                                          \
+        _W("Plugin without library."); \
+        return;                                \
+    }
+
+namespace Jobs {
+namespace PluginInstall {
+PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) :
+    DPL::TaskDecl<PluginInstallTask>(this),
+    m_context(inCont),
+    m_pluginHandle(0),
+    m_dataFromConfigXML(true)
+{
+    AddStep(&PluginInstallTask::stepCheckPluginPath);
+    AddStep(&PluginInstallTask::stepParseConfigFile);
+    AddStep(&PluginInstallTask::stepFindPluginLibrary);
+    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()
+{
+    _D("Plugin installation: step CheckPluginPath");
+
+    if(!m_context->pluginFilePath.Exists()){
+        ThrowMsg(Exceptions::PluginPathFailed,
+                 "No such path");
+    }
+
+    SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Path to plugin verified");
+}
+
+void PluginInstallTask::stepParseConfigFile()
+{
+    _D("Plugin installation: step parse config file");
+
+    if(!m_context->pluginFilePath.getMetaFile().Exists()){
+        m_dataFromConfigXML = false;
+        return;
+    }
+
+    _D("Plugin Config file::%s", m_context->pluginFilePath.getMetaFile().Fullpath().c_str());
+
+    Try
+    {
+        PluginMetafileReader reader;
+        reader.initialize(m_context->pluginFilePath.getMetaFile());
+        reader.read(m_pluginInfo);
+
+        FOREACH(it, m_pluginInfo.m_featureContainer)
+        {
+            _D("Parsed feature : %s", it->m_name.c_str());
+            FOREACH(devCap, it->m_deviceCapabilities) {
+                _D("  |  DevCap : %s", (*devCap).c_str());
+            }
+        }
+
+        SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Config file analyzed");
+    }
+    Catch(ValidationCore::ParserSchemaException::Base)
+    {
+        _E("Error during file processing %s", m_context->pluginFilePath.getMetaFile().Fullpath().c_str());
+        ThrowMsg(Exceptions::PluginMetafileFailed,
+                 "Metafile error");
+    }
+}
+
+void PluginInstallTask::stepFindPluginLibrary()
+{
+    if (m_dataFromConfigXML) {
+        return;
+    }
+    _D("Plugin installation: step find plugin library");
+    _D("Plugin .so: %s", m_context->pluginFilePath.getLibraryName().c_str());
+    m_pluginInfo.m_libraryName = m_context->pluginFilePath.getLibraryName();
+}
+
+void PluginInstallTask::stepCheckIfAlreadyInstalled()
+{
+    if (PluginDAO::isPluginInstalled(m_pluginInfo.m_libraryName)) {
+        ThrowMsg(Exceptions::PluginAlreadyInstalled,
+                 "Plugin already installed");
+    }
+
+    SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_EXISTS_CHECK, "Check if plugin exist");
+}
+
+void PluginInstallTask::stepLoadPluginLibrary()
+{
+    _D("Plugin installation: step load library");
+
+    DISABLE_IF_PLUGIN_WITHOUT_LIB()
+
+    _D("Loading plugin: %s", m_context->pluginFilePath.getLibraryName().c_str());
+
+    fprintf(stderr, " - Try to dlopen() : [%s] ", m_context->pluginFilePath.getLibraryPath().Fullpath().c_str());
+
+    void *dlHandle = dlopen( m_context->pluginFilePath.getLibraryPath().Fullpath().c_str(), RTLD_LAZY);
+    if (dlHandle == NULL) {
+        const char* error = (const char*)dlerror();
+        fprintf(stderr,
+                "-> Failed!\n   %s\n",
+                (error != NULL ? error : "unknown"));
+        _E("Failed to load plugin: %s. Reason: %s",
+            m_context->pluginFilePath.getLibraryName().c_str(), (error != NULL ? error : "unknown"));
+        ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+    }
+
+    fprintf(stderr, "-> Done.\n");
+
+    const js_entity_definition_t *rawEntityList = NULL;
+    get_widget_entity_map_proc *getWidgetEntityMapProcPtr = NULL;
+
+    getWidgetEntityMapProcPtr =
+        reinterpret_cast<get_widget_entity_map_proc *>(dlsym(dlHandle,
+                                                             PLUGIN_GET_CLASS_MAP_PROC_NAME));
+
+    if (getWidgetEntityMapProcPtr) {
+        rawEntityList = (*getWidgetEntityMapProcPtr)();
+    } else {
+        rawEntityList =
+            static_cast<const js_entity_definition_t *>(dlsym(dlHandle,
+                                                              PLUGIN_CLASS_MAP_NAME));
+    }
+
+    if (rawEntityList == NULL) {
+        dlclose(dlHandle);
+        _E("Failed to read class name %s", m_context->pluginFilePath.getLibraryName().c_str());
+        ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+    }
+
+    if (!m_dataFromConfigXML) {
+        on_widget_init_proc *onWidgetInitProc =
+            reinterpret_cast<on_widget_init_proc *>(
+                dlsym(dlHandle, PLUGIN_WIDGET_INIT_PROC_NAME));
+
+        if (NULL == onWidgetInitProc) {
+            dlclose(dlHandle);
+            _E("Failed to read onWidgetInit symbol %s", m_context->pluginFilePath.getLibraryName().c_str());
+            ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+        }
+
+        // obtain feature -> dev-cap mapping
+        feature_mapping_interface_t mappingInterface = { NULL, NULL, NULL };
+        (*onWidgetInitProc)(&mappingInterface);
+
+        if (!mappingInterface.featGetter || !mappingInterface.release ||
+            !mappingInterface.dcGetter)
+        {
+            _E("Failed to obtain mapping interface from .so");
+            ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+        }
+
+        feature_mapping_t* devcapMapping = mappingInterface.featGetter();
+
+        _D("Getting mapping from features to device capabilities");
+
+        for (size_t i = 0; i < devcapMapping->featuresCount; ++i) {
+            PluginMetafileData::Feature feature;
+            feature.m_name = devcapMapping->features[i].feature_name;
+
+            _D("Feature: %s", feature.m_name.c_str());
+
+            const devcaps_t* dc =
+                mappingInterface.dcGetter(
+                    devcapMapping,
+                    devcapMapping->features[i].
+                        feature_name);
+
+            if (dc) {
+                _D("devcaps count: %d", dc->devCapsCount);
+
+                for (size_t j = 0; j < dc->devCapsCount; ++j) {
+                    _D("devcap: %s", dc->deviceCaps[j]);
+                    feature.m_deviceCapabilities.insert(dc->deviceCaps[j]);
+                }
+            }
+
+            m_pluginInfo.m_featureContainer.insert(feature);
+        }
+
+        mappingInterface.release(devcapMapping);
+    }
+
+    m_libraryObjects = PluginObjectsPtr(new PluginObjects());
+    const js_entity_definition_t *rawEntityListIterator = rawEntityList;
+
+    _D("#####");
+    _D("##### Plugin: %s supports new plugin API",
+        m_context->pluginFilePath.getLibraryName().c_str());
+    _D("#####");
+
+    while (rawEntityListIterator->parent_name != NULL &&
+           rawEntityListIterator->object_name != NULL)
+    {
+        _D("#####     [%s]: ", rawEntityListIterator->object_name);
+        _D("#####     Parent: %s", rawEntityListIterator->parent_name);
+        _D("#####");
+
+        m_libraryObjects->addObjects(rawEntityListIterator->parent_name,
+                                     rawEntityListIterator->object_name);
+
+        ++rawEntityListIterator;
+    }
+
+    // Unload library
+    if (dlclose(dlHandle) != 0) {
+        _E("Cannot close plugin handle");
+    } else {
+        _D("Library is unloaded");
+    }
+
+    // Load export table
+    _D("Library successfuly loaded and parsed");
+
+    SET_PLUGIN_INSTALL_PROGRESS(LOADING_LIBRARY, "Library loaded and analyzed");
+}
+
+void PluginInstallTask::stepRegisterPlugin()
+{
+    _D("Plugin installation: step register Plugin");
+
+    m_pluginHandle =
+        PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath.Fullpath());
+
+    SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered");
+}
+
+void PluginInstallTask::stepRegisterFeatures()
+{
+    _D("Plugin installation: step register features");
+
+    FOREACH(it, m_pluginInfo.m_featureContainer)
+    {
+        _D("PluginHandle: %d", m_pluginHandle);
+        FeatureDAO::RegisterFeature(*it, m_pluginHandle);
+    }
+    SET_PLUGIN_INSTALL_PROGRESS(REGISTER_FEATURES, "Features registered");
+}
+
+void PluginInstallTask::stepRegisterPluginObjects()
+{
+    _D("Plugin installation: step register objects");
+
+    DISABLE_IF_PLUGIN_WITHOUT_LIB()
+
+    //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)) {
+            _D("Dependency from the same library. ignored");
+            continue;
+        }
+
+        PluginDAO::registerPluginRequiredObject(*it, m_pluginHandle);
+    }
+
+    SET_PLUGIN_INSTALL_PROGRESS(REGISTER_OBJECTS, "Plugin Objects registered");
+}
+
+void PluginInstallTask::stepResolvePluginDependencies()
+{
+    _D("Plugin installation: step resolve dependencies ");
+
+    //DISABLE_IF_PLUGIN_WITHOUT_LIB
+    if (m_pluginInfo.m_libraryName.empty()) {
+        PluginDAO::setPluginInstallationStatus(
+            m_pluginHandle,
+            PluginDAO::
+                INSTALLATION_COMPLETED);
+        //Installation completed
+        m_context->pluginHandle = m_pluginHandle;
+        m_context->installationCompleted = true;
+        _W("Plugin without library.");
+        return;
+    }
+
+    PluginHandleSetPtr handles = PluginHandleSetPtr(new PluginHandleSet);
+
+    DbPluginHandle handle = INVALID_PLUGIN_HANDLE;
+
+    //register requiredObjects
+    FOREACH(it, *(m_libraryObjects->getDependentObjects()))
+    {
+        if (m_libraryObjects->hasObject(*it)) {
+            _D("Dependency from the same library. ignored");
+            continue;
+        }
+
+        handle = PluginDAO::getPluginHandleForImplementedObject(*it);
+        if (handle == INVALID_PLUGIN_HANDLE) {
+            _E("Library implementing: %s NOT FOUND", (*it).c_str());
+            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_mobile/jobs/plugin_install/plugin_install_task.h b/src_mobile/jobs/plugin_install/plugin_install_task.h
new file mode 100644 (file)
index 0000000..c7a5d8c
--- /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    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_pluginInfo;
+
+    //Plugin LibraryObjects
+    PluginObjectsPtr m_libraryObjects;
+
+    WrtDB::DbPluginHandle m_pluginHandle;
+
+    bool m_dataFromConfigXML;
+
+    //steps
+    void stepCheckPluginPath();
+    void stepFindPluginLibrary();
+    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_mobile/jobs/plugin_install/plugin_installer_context.h b/src_mobile/jobs/plugin_install/plugin_installer_context.h
new file mode 100644 (file)
index 0000000..1efd504
--- /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_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_path.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
+    };
+
+    PluginPath pluginFilePath;           ///< plugin directory
+    PluginPath metaFilePath;
+    bool m_dataFromConfigXML;
+    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_mobile/jobs/plugin_install/plugin_installer_errors.h b/src_mobile/jobs/plugin_install/plugin_installer_errors.h
new file mode 100644 (file)
index 0000000..11c7f88
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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>
+#include <job_exception_error.h>
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace PluginInstall {
+namespace Exceptions {
+
+DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown)
+DECLARE_JOB_EXCEPTION(Base, PluginPathFailed, ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PluginMetafileFailed, ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PluginAlreadyInstalled,
+        ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PluginLibraryError, ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, InstallationWaitingError,
+        ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, UnknownError, ErrorUnknown)
+} //namespace
+} //namespace
+} //namespace
+
+#endif
+//WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_INSTALLER_ERRORS_H_
+
diff --git a/src_mobile/jobs/plugin_install/plugin_installer_struct.h b/src_mobile/jobs/plugin_install/plugin_installer_struct.h
new file mode 100644 (file)
index 0000000..c253897
--- /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::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_mobile/jobs/plugin_install/plugin_metafile_reader.cpp b/src_mobile/jobs/plugin_install/plugin_metafile_reader.cpp
new file mode 100644 (file)
index 0000000..c7df516
--- /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.
+ */
+/**
+ * @file        plugin_metafile_reader.cpp
+ * @author      Grzegorz Krawczyk(g.krawczyk@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+
+#include "plugin_metafile_reader.h"
+#include <plugin_path.h>
+
+using namespace WrtDB;
+
+namespace {
+const std::string XML_NAMESPACE = "";
+
+const std::string TOKEN_LIBRARY_NAME = "library-name";
+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_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::initialize(const PluginPath &filename)
+{
+    m_parserSchema.initialize(filename.Fullpath(),
+                              true,
+                              ValidationCore::SaxReader::VALIDATION_DTD,
+                              std::string());
+}
+
+void PluginMetafileReader::read(WrtDB::PluginMetafileData &data)
+{
+    m_parserSchema.read(data);
+}
+
+void PluginMetafileReader::blankFunction(PluginMetafileData & /* data */)
+{}
+
+void PluginMetafileReader::tokenEndLibraryName(PluginMetafileData &data)
+{
+    data.m_libraryName = m_parserSchema.getText();
+}
+
+void PluginMetafileReader::tokenEndApiFeature(PluginMetafileData &data)
+{
+    data.m_featureContainer.insert(m_feature);
+    m_feature.m_deviceCapabilities.clear();
+}
+
+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_mobile/jobs/plugin_install/plugin_metafile_reader.h b/src_mobile/jobs/plugin_install/plugin_metafile_reader.h
new file mode 100644 (file)
index 0000000..a3a3068
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 PluginPath;
+
+class PluginMetafileReader
+{
+  public:
+    PluginMetafileReader();
+
+    void initialize(const PluginPath &filename);
+
+    void read(WrtDB::PluginMetafileData &data);
+
+  private:
+    void blankFunction(WrtDB::PluginMetafileData &data);
+
+    void tokenEndLibraryName(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_mobile/jobs/plugin_install/plugin_objects.cpp b/src_mobile/jobs/plugin_install/plugin_objects.cpp
new file mode 100644 (file)
index 0000000..9235f47
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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 <installer_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()) {
+        _E("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()) {
+        _E("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_mobile/jobs/plugin_install/plugin_objects.h b/src_mobile/jobs/plugin_install/plugin_objects.h
new file mode 100644 (file)
index 0000000..0b27a14
--- /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        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 <memory>
+#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 std::shared_ptr<PluginObjects> PluginObjectsPtr;
+
+#endif
diff --git a/src_mobile/jobs/widget_install/ace_registration.cpp b/src_mobile/jobs/widget_install/ace_registration.cpp
new file mode 100644 (file)
index 0000000..6596d47
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2012 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_registration.cpp
+ * @author  Andrzej Surdej (a.surdej@gmail.com)
+ * @version 1.0
+ * @brief   Translate structures to ace api - implementation file
+ */
+
+#include <ace_registration.h>
+#include <dpl/foreach.h>
+#include <ace_api_install.h>
+
+#include <installer_log.h>
+
+namespace {
+char* toAceString(const DPL::OptionalString& os)
+{
+    if (!os.IsNull()) {
+        return strdup(DPL::ToUTF8String(*os).c_str());
+    } else {
+        return NULL;
+    }
+}
+
+char* toAceString(const std::string& str)
+{
+    if (!str.empty()) {
+        return strdup(str.c_str());
+    } else {
+        return NULL;
+    }
+}
+} //anonymous namespace
+
+namespace AceApi {
+bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle,
+                       const WrtDB::WidgetRegisterInfo& widgetConfig,
+                       const WrtDB::WidgetCertificateDataList& certList)
+{
+    _D("Updating Ace database");
+    struct widget_info wi;
+
+    switch (widgetConfig.webAppType.appType) {
+    case WrtDB::APP_TYPE_TIZENWEBAPP:
+        wi.type = Tizen;
+        break;
+    default:
+        _E("Unknown application type");
+        return false;
+    }
+
+    wi.id = toAceString(widgetConfig.configInfo.widget_id);
+    wi.version = toAceString(widgetConfig.configInfo.version);
+    wi.author = toAceString(widgetConfig.configInfo.authorName);
+    wi.shareHerf = strdup(widgetConfig.shareHref.c_str());
+    _D("Basic data converted. Certificates begin.");
+
+    //one more element for NULL termination
+    _D("Found: %d certificates", certList.size());
+    ace_certificate_data** certData = new ace_certificate_data *
+        [certList.size() + 1];
+    certData[certList.size()] = NULL; // last element set to NULL
+
+    int i = 0;
+    FOREACH(it, certList)
+    {
+        certData[i] = new ace_certificate_data;
+        switch (it->owner) {
+        case WrtDB::WidgetCertificateData::AUTHOR:
+            certData[i]->owner = AUTHOR;
+            break;
+        case WrtDB::WidgetCertificateData::DISTRIBUTOR:
+            certData[i]->owner = DISTRIBUTOR;
+            break;
+        default:
+            _D("Unknown owner type of cert");
+            certData[i]->owner = UNKNOWN;
+            break;
+        }
+        switch (it->type) {
+        case WrtDB::WidgetCertificateData::ENDENTITY:
+            certData[i]->type = ENDENTITY;
+            break;
+        case WrtDB::WidgetCertificateData::ROOT:
+            certData[i]->type = ROOT;
+            break;
+        default:
+            _E("Unknown type of cert");
+            certData[i]->type = ENDENTITY;
+            break;
+        }
+        certData[i]->chain_id = it->chainId;
+
+        certData[i]->md5_fp = toAceString(it->strMD5Fingerprint);
+        certData[i]->sha1_fp = toAceString(it->strSHA1Fingerprint);
+        certData[i]->common_name =
+            toAceString(DPL::ToUTF8String(it->strCommonName));
+        ++i;
+    }
+
+    _D("Registerign widget in ace");
+    ace_return_t retval = ace_register_widget(
+            static_cast<ace_widget_handle_t>(widgetHandle), &wi, certData);
+
+    //clean up - WidgetInfo
+    free(wi.author);
+    free(wi.id);
+    free(wi.shareHerf);
+    free(wi.version);
+
+    //free cert list
+    i = 0;
+    while (certData[i] != NULL) {
+        free(certData[i]->common_name);
+        free(certData[i]->md5_fp);
+        free(certData[i]->sha1_fp);
+        delete certData[i];
+        ++i;
+    }
+    delete[] certData;
+    return retval == ACE_OK;
+}
+bool registerAceWidgetFromDB(const WrtDB::DbWidgetHandle& widgetHandle)
+{
+    using namespace WrtDB;
+    _D("Updating Ace database from Widget DB");
+    struct widget_info wi;
+    DPL::OptionalString os;
+    WrtDB::WidgetCertificateDataList certList;
+
+    Try {
+        WidgetDAOReadOnly dao(widgetHandle);
+
+        WidgetType type = dao.getWidgetType();
+        if (type == WrtDB::APP_TYPE_TIZENWEBAPP) {
+            wi.type = Tizen;
+        } else {
+            _E("Unknown application type");
+            return false;
+        }
+
+        wi.id = toAceString(dao.getGUID());
+        wi.version = toAceString(dao.getVersion());
+        wi.author = toAceString(dao.getAuthorName());
+        wi.shareHerf = strdup(dao.getShareHref().c_str());
+        _D("Basic data converted. Certificates begin.");
+        certList = dao.getCertificateDataList();
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        _E("Widget does not exist");
+        return false;
+    }
+
+    //one more element for NULL termination
+    _D("Found: %d certificates", certList.size());
+    ace_certificate_data** certData = new ace_certificate_data *
+        [certList.size() + 1];
+    certData[certList.size()] = NULL; // last element set to NULL
+
+    int i = 0;
+    FOREACH(it, certList)
+    {
+        certData[i] = new ace_certificate_data;
+        switch (it->owner) {
+        case WrtDB::WidgetCertificateData::AUTHOR:
+            certData[i]->owner = AUTHOR;
+            break;
+        case WrtDB::WidgetCertificateData::DISTRIBUTOR:
+            certData[i]->owner = DISTRIBUTOR;
+            break;
+        default:
+            _D("Unknown owner type of cert");
+            certData[i]->owner = UNKNOWN;
+            break;
+        }
+        switch (it->type) {
+        case WrtDB::WidgetCertificateData::ENDENTITY:
+            certData[i]->type = ENDENTITY;
+            break;
+        case WrtDB::WidgetCertificateData::ROOT:
+            certData[i]->type = ROOT;
+            break;
+        default:
+            _E("Unknown type of cert");
+            certData[i]->type = ENDENTITY;
+            break;
+        }
+        certData[i]->chain_id = it->chainId;
+
+        certData[i]->md5_fp = toAceString(it->strMD5Fingerprint);
+        certData[i]->sha1_fp = toAceString(it->strSHA1Fingerprint);
+        certData[i]->common_name =
+            toAceString(DPL::ToUTF8String(it->strCommonName));
+        ++i;
+    }
+
+    _D("Registerign widget in ace");
+    ace_return_t retval = ace_register_widget(
+            static_cast<ace_widget_handle_t>(widgetHandle), &wi, certData);
+
+    //clean up - WidgetInfo
+    free(wi.author);
+    free(wi.id);
+    free(wi.shareHerf);
+    free(wi.version);
+
+    //free cert list
+    i = 0;
+    while (certData[i] != NULL) {
+        free(certData[i]->common_name);
+        free(certData[i]->md5_fp);
+        free(certData[i]->sha1_fp);
+        delete certData[i];
+        ++i;
+    }
+    delete[] certData;
+    return retval == ACE_OK;
+}
+}
diff --git a/src_mobile/jobs/widget_install/ace_registration.h b/src_mobile/jobs/widget_install/ace_registration.h
new file mode 100644 (file)
index 0000000..f98c3ce
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 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_registration.h
+ * @author  Andrzej Surdej (a.surdej@gmail.com)
+ * @version 1.0
+ * @brief   Translate structures to ace api - header file
+ */
+#ifndef WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_
+#define WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+namespace AceApi {
+bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle,
+                       const WrtDB::WidgetRegisterInfo& widgetConfig,
+                       const WrtDB::WidgetCertificateDataList& certList);
+bool registerAceWidgetFromDB(const WrtDB::DbWidgetHandle& widgetHandle);
+}
+
+#endif  /* WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_ */
+
diff --git a/src_mobile/jobs/widget_install/directory_api.cpp b/src_mobile/jobs/widget_install/directory_api.cpp
new file mode 100644 (file)
index 0000000..dd8aa07
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 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    directory_api.cpp
+ * @author  Soyoung Kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   directory api - implementation file
+ */
+
+#include <cerrno>
+#include <directory_api.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fstream>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/errno_string.h>
+#include <installer_log.h>
+
+namespace DirectoryApi {
+bool DirectoryCopy(std::string source, std::string dest)
+{
+    DIR* dir = opendir(source.c_str());
+    if (NULL == dir) {
+        return false;
+    }
+
+    struct dirent dEntry;
+    struct dirent *dEntryResult;
+    int return_code;
+
+    do {
+        struct stat statInfo;
+        return_code = readdir_r(dir, &dEntry, &dEntryResult);
+        if (dEntryResult != NULL && return_code == 0) {
+            std::string fileName = dEntry.d_name;
+            std::string fullName = source + "/" + fileName;
+
+            if (stat(fullName.c_str(), &statInfo) != 0) {
+                closedir(dir);
+                return false;
+            }
+
+            if (S_ISDIR(statInfo.st_mode)) {
+                if (("." == fileName) || (".." == fileName)) {
+                    continue;
+                }
+                std::string destFolder = dest + "/" + fileName;
+                WrtUtilMakeDir(destFolder);
+
+                if (!DirectoryCopy(fullName, destFolder)) {
+                    closedir(dir);
+                    return false;
+                }
+            }
+
+            std::string destFile = dest + "/" + fileName;
+            std::ifstream infile(fullName);
+            std::ofstream outfile(destFile);
+            outfile << infile.rdbuf();
+            outfile.close();
+            infile.close();
+
+            errno = 0;
+            if (-1 == TEMP_FAILURE_RETRY(chown(destFile.c_str(),
+                                               statInfo.st_uid,
+                                               statInfo.st_gid))) {
+                int error = errno;
+                _E("Failed to change owner [%s]", DPL::GetErrnoString(error).c_str());
+            }
+        }
+    } while (dEntryResult != NULL && return_code == 0);
+    closedir(dir);
+    return true;
+}
+}
diff --git a/src_mobile/jobs/widget_install/directory_api.h b/src_mobile/jobs/widget_install/directory_api.h
new file mode 100644 (file)
index 0000000..1632528
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 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    directory_api.h
+ * @author  Soyoung Kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   directory api - header file
+ */
+#ifndef WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_
+#define WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_
+
+#include<string>
+
+namespace DirectoryApi {
+bool DirectoryCopy(std::string source, std::string dest);
+}
+
+#endif  /* WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_ */
+
diff --git a/src_mobile/jobs/widget_install/job_widget_install.cpp b/src_mobile/jobs/widget_install/job_widget_install.cpp
new file mode 100644 (file)
index 0000000..58e2068
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * 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 <string>
+#include <sys/time.h>
+#include <ctime>
+#include <cstdlib>
+#include <limits.h>
+#include <regex.h>
+
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <dpl/localization/w3c_file_localization.h>
+
+#include <pkg-manager/pkgmgr_signal.h>
+#include <app_manager.h>
+
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_certify.h>
+#include <widget_install/task_certify_level.h>
+#include <widget_install/task_process_config.h>
+#include <widget_install/task_file_manipulation.h>
+#include <widget_install/task_ace_check.h>
+#include <widget_install/task_smack.h>
+#include <widget_install/task_manifest_file.h>
+#include <widget_install/task_prepare_files.h>
+#include <widget_install/task_recovery.h>
+#include <widget_install/task_install_ospsvc.h>
+#include <widget_install/task_update_files.h>
+#include <widget_install/task_database.h>
+#include <widget_install/task_remove_backup.h>
+#include <widget_install/task_encrypt_resource.h>
+#include <widget_install/task_pkg_info_update.h>
+#include <widget_install/task_commons.h>
+#include <widget_install/task_prepare_reinstall.h>
+#include <widget_install/task_configuration.h>
+#include <widget_install/task_user_data_manipulation.h>
+
+#include <widget_install_to_external.h>
+#include <widget_install/widget_unzip.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+JobWidgetInstall::JobWidgetInstall(
+    std::string const &widgetPath,
+    std::string const &tzPkgId,
+    const Jobs::WidgetInstall::WidgetInstallationStruct &
+    installerStruct) :
+    Job(UnknownInstallation),
+    JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct>(installerStruct),
+    m_exceptionCaught(Jobs::Exceptions::Success)
+{
+    m_installerContext.mode = m_jobStruct.m_installMode;
+    m_installerContext.requestedPath = widgetPath;
+    m_jobStruct.pkgmgrInterface->setPkgname(tzPkgId);
+
+    //start configuration of installation
+    AddTask(new TaskConfiguration(m_installerContext));
+
+    // Init installer context
+    m_installerContext.installStep = InstallerContext::INSTALL_START;
+    m_installerContext.job = this;
+
+    m_installerContext.callerPkgId
+            = DPL::FromUTF8String(m_jobStruct.pkgmgrInterface->getCallerId());
+    _D("Caller Package Id : %s", DPL::ToUTF8String(m_installerContext.callerPkgId).c_str());
+}
+
+void JobWidgetInstall::appendNewInstallationTaskList()
+{
+    _D("Configure installation succeeded");
+    m_installerContext.job->SetProgressFlag(true);
+
+    AddTask(new TaskRecovery(m_installerContext));
+
+    AddTask(new TaskFileManipulation(m_installerContext));
+    AddTask(new TaskProcessConfig(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+    {
+        AddTask(new TaskPrepareFiles(m_installerContext));
+    }
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskUserDataManipulation(m_installerContext));
+    if (m_installerContext.needEncryption) {
+        AddTask(new TaskEncryptResource(m_installerContext));
+    }
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP)
+    {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+    AddTask(new TaskDatabase(m_installerContext));
+    AddTask(new TaskAceCheck(m_installerContext));
+    AddTask(new TaskSmack(m_installerContext));
+    AddTask(new TaskPkgInfoUpdate(m_installerContext));
+}
+
+void JobWidgetInstall::appendUpdateInstallationTaskList()
+{
+    _D("Configure installation updated");
+    _D("Widget Update");
+    m_installerContext.job->SetProgressFlag(true);
+
+    if (m_installerContext.mode.command ==
+        InstallMode::Command::REINSTALL)
+    {
+        AddTask(new TaskPrepareReinstall(m_installerContext));
+    }
+
+    if (m_installerContext.mode.extension !=
+            InstallMode::ExtensionType::DIR) {
+        AddTask(new TaskUpdateFiles(m_installerContext));
+        AddTask(new TaskFileManipulation(m_installerContext));
+    }
+
+    AddTask(new TaskProcessConfig(m_installerContext));
+
+    if (m_installerContext.widgetConfig.packagingType ==
+        WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+    {
+        AddTask(new TaskPrepareFiles(m_installerContext));
+    }
+
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskUserDataManipulation(m_installerContext));
+    if (m_installerContext.needEncryption) {
+        AddTask(new TaskEncryptResource(m_installerContext));
+    }
+
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP)
+    {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+
+    AddTask(new TaskDatabase(m_installerContext));
+    AddTask(new TaskAceCheck(m_installerContext));
+    //TODO: remove widgetHandle from this task and move before database task
+    // by now widget handle is needed in ace check
+    // Any error in acecheck while update will break widget
+    AddTask(new TaskSmack(m_installerContext));
+    AddTask(new TaskRemoveBackupFiles(m_installerContext));
+    AddTask(new TaskPkgInfoUpdate(m_installerContext));
+}
+
+void JobWidgetInstall::SendProgress()
+{
+    using namespace PackageManager;
+    if (GetProgressFlag() != false) {
+        if (GetInstallerStruct().progressCallback != NULL) {
+            // send progress signal of pkgmgr
+            GetInstallerStruct().pkgmgrInterface->sendProgress(GetProgressPercent());
+
+            _D("Call widget install progressCallback");
+            GetInstallerStruct().progressCallback(
+                GetInstallerStruct().userParam,
+                GetProgressPercent(),
+                GetProgressDescription());
+        }
+    }
+}
+
+void JobWidgetInstall::SendProgressIconPath(const std::string &path)
+{
+    using namespace PackageManager;
+    if (GetProgressFlag() != false) {
+        if (GetInstallerStruct().progressCallback != NULL) {
+            // send progress signal of pkgmgr
+            GetInstallerStruct().pkgmgrInterface->sendIconPath(path);
+        }
+    }
+}
+
+void JobWidgetInstall::SendFinishedSuccess()
+{
+    using namespace PackageManager;
+    // TODO : sync should move to separate task.
+    sync();
+
+    if (INSTALL_LOCATION_TYPE_PREFER_EXTERNAL == m_installerContext.locationType) {
+        if (m_installerContext.isUpdateMode) {
+            WidgetInstallToExtSingleton::Instance().postUpgrade(true);
+        } else {
+            WidgetInstallToExtSingleton::Instance().postInstallation(true);
+        }
+        WidgetInstallToExtSingleton::Instance().deinitialize();
+    }
+
+    // remove widget install information file
+    unlink(m_installerContext.installInfo.c_str());
+
+    //inform widget info
+    JobWidgetInstall::displayWidgetInfo();
+
+    TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
+
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    _D("Call widget install successfinishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          DPL::ToUTF8String(
+                                              tizenId), Jobs::Exceptions::Success);
+}
+
+void JobWidgetInstall::SendFinishedFailure()
+{
+    using namespace PackageManager;
+    // remove widget install information file
+    unlink(m_installerContext.installInfo.c_str());
+
+    _E("Error number: %d", m_exceptionCaught);
+    _E("Message: %s", m_exceptionMessage.c_str());
+    TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
+
+    _D("Call widget install failure finishedCallback");
+
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          DPL::ToUTF8String(
+                                              tizenId), m_exceptionCaught);
+}
+
+void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
+{
+    m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
+    m_exceptionMessage = e.GetMessage();
+}
+
+void JobWidgetInstall::displayWidgetInfo()
+{
+    WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
+
+    std::ostringstream out;
+    WidgetLocalizedInfo localizedInfo =
+        W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
+
+    out << std::endl <<
+    "===================================== INSTALLED WIDGET INFO =========" \
+    "============================";
+    out << std::endl << "Name:                        " << localizedInfo.name;
+    out << std::endl << "AppId:                     " << dao.getTzAppId();
+    WidgetSize size = dao.getPreferredSize();
+    out << std::endl << "Width:                       " << size.width;
+    out << std::endl << "Height:                      " << size.height;
+    out << std::endl << "Start File:                  " <<
+    W3CFileLocalization::getStartFile(dao.getTzAppId());
+    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 distributor signed:   " <<
+    dao.isDistributorSigned();
+    out << std::endl << "Widget trusted:              " << dao.isTrusted();
+
+    OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
+    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;
+
+    _D("%s", out.str().c_str());
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/job_widget_install.h b/src_mobile/jobs/widget_install/job_widget_install.h
new file mode 100644 (file)
index 0000000..a87337d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 <job.h>
+#include <job_base.h>
+#include <dpl/utils/widget_version.h>
+#include "widget_installer_struct.h"
+#include <widget_install/widget_install_context.h>
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+typedef JobProgressBase<InstallerContext::InstallStep, InstallerContext::INSTALL_END> InstallerBase;
+typedef JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct> WidgetInstallationBase;
+
+class JobWidgetInstall :
+    public Job,
+    public InstallerBase,
+    public WidgetInstallationBase
+
+{
+  private:
+    InstallerContext m_installerContext;
+
+    Jobs::Exceptions::Type m_exceptionCaught;
+    std::string m_exceptionMessage;
+
+  public:
+    /**
+     * @brief Automaticaly sets installation process
+     */
+    JobWidgetInstall(std::string const & widgetPath,
+         std::string const &tzPkgId,
+         const Jobs::WidgetInstall::WidgetInstallationStruct &installerStruct);
+
+    //overrides
+    void SendProgress();
+    void SendFinishedSuccess();
+    void SendFinishedFailure();
+    void SendProgressIconPath(const std::string &path);
+
+    void SaveExceptionData(const Jobs::JobExceptionBase&);
+    void displayWidgetInfo();
+
+    //execution paths
+    void appendNewInstallationTaskList();
+    void appendUpdateInstallationTaskList();
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_
diff --git a/src_mobile/jobs/widget_install/languages.def b/src_mobile/jobs/widget_install/languages.def
new file mode 100644 (file)
index 0000000..e9439b6
--- /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_mobile/jobs/widget_install/manifest.cpp b/src_mobile/jobs/widget_install/manifest.cpp
new file mode 100644 (file)
index 0000000..1e02cfa
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2012 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    manifest.cpp
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ */
+
+#include "manifest.h"
+#include "libxml_utils.h"
+#include <widget_install/task_manifest_file.h>
+#include <dpl/foreach.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+void writeElement(xmlTextWriterPtr writer, const char * name, DPL::String body)
+{
+    int state = xmlTextWriterWriteElement(writer, BAD_CAST name,
+                                          BAD_CAST DPL::ToUTF8String(
+                                              body).c_str());
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteElement failed");
+    }
+}
+
+void writeText(xmlTextWriterPtr writer, DPL::String text)
+{
+    int state = xmlTextWriterWriteString(writer,
+                                         BAD_CAST DPL::ToUTF8String(text).c_str());
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteText failed");
+    }
+}
+
+void writeElement(xmlTextWriterPtr writer, const char * name, const char * body)
+{
+    int state = xmlTextWriterWriteElement(writer, BAD_CAST name, BAD_CAST body);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteElement failed");
+    }
+}
+
+void writeElementWithOneAttribute(xmlTextWriterPtr writer,
+                                  const char * name,
+                                  DPL::String body,
+                                  const char * nameAttr,
+                                  DPL::String bodyAttr,
+                                  bool condition = true)
+{
+    startElement(writer, name);
+    writeAttribute(writer, nameAttr, bodyAttr, condition);
+    writeText(writer, body);
+    endElement(writer);
+}
+
+void startElement(xmlTextWriterPtr writer, const char * name)
+{
+    int state = xmlTextWriterStartElement(writer, BAD_CAST name);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterStartElement failed");
+    }
+}
+
+void endElement(xmlTextWriterPtr writer)
+{
+    int state = xmlTextWriterEndElement(writer);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterEndElement failed");
+    }
+}
+
+void writeAttribute(xmlTextWriterPtr writer,
+                    const char * name,
+                    DPL::String body,
+                    bool condition = true)
+{
+    if (!condition) {
+        return;
+    }
+    int state = xmlTextWriterWriteAttribute(writer, BAD_CAST name,
+                                            BAD_CAST DPL::ToUTF8String(
+                                                body).c_str());
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error,
+                 "xmlTextWriterWriteAttribute failed");
+    }
+}
+
+void writeAttribute(xmlTextWriterPtr writer,
+                    const char * name,
+                    const char * body,
+                    bool condition = true)
+{
+    if (!condition) {
+        return;
+    }
+    int state = xmlTextWriterWriteAttribute(writer,
+                                            BAD_CAST name,
+                                            BAD_CAST body);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error,
+                 "xmlTextWriterWriteAttribute failed");
+    }
+}
+
+void Manifest::generate(DPL::String filename)
+{
+    xmlTextWriterPtr writer;
+    int state;
+
+    //compression set to 0
+    writer = xmlNewTextWriterFilename(DPL::ToUTF8String(filename).c_str(), 0);
+
+    if (writer == NULL) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlNewTextWriterFilename failed");
+    }
+    state = xmlTextWriterSetIndent(writer, 1);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterSetIndent failed");
+    }
+
+    state = xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterStartDocument failed");
+    }
+    this->serialize(writer);
+    state = xmlTextWriterEndDocument(writer);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterEndDocument failed");
+    }
+    if (writer != NULL) {
+        xmlFreeTextWriter(writer);
+        writer = NULL;
+    }
+}
+
+void Manifest::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "manifest");
+    {
+        writeAttribute(writer, "xmlns", "http://tizen.org/ns/packages");
+        writeAttribute(writer, "package", this->package);
+        writeAttribute(writer, "type", this->type);
+        writeAttribute(writer, "version", this->version);
+        if (!this->installLocation.IsNull()) {
+            writeAttribute(writer, "install-location", (*this->installLocation));
+        }
+        writeAttribute(writer, "storeclient-id", this->storeClientId,
+                !this->storeClientId.empty());
+
+        FOREACH(l, this->label)
+        {
+            writeElementWithOneAttribute(writer, "label", l->getString(),
+                                         "xml:lang", l->getLang(), l->hasLang());
+        }
+        FOREACH(i, this->icon)
+        {
+            writeElementWithOneAttribute(writer, "icon", i->getString(),
+                                         "xml:lang", i->getLang(), i->hasLang());
+        }
+        FOREACH(a, this->author)
+        {
+            a->serialize(writer);
+        }
+        FOREACH(d, this->description)
+        {
+            writeElementWithOneAttribute(writer, "description", d->getString(),
+                                         "xml:lang", d->getLang(), d->hasLang());
+        }
+        //FOREACH(c, this->compatibility) { c->serialize(writer); }
+        //FOREACH(d, this->deviceProfile) { d->serialize(writer); }
+        FOREACH(s, this->serviceApplication) {
+            s->serialize(writer);
+        }
+        FOREACH(u, this->uiApplication) {
+            u->serialize(writer);
+        }
+        FOREACH(i, this->imeApplication) {
+            i->serialize(writer);
+        }
+        //FOREACH(f, this->font) { f->serialize(writer); }
+        FOREACH(l, this->livebox) {
+            l->serialize(writer);
+        }
+        FOREACH(acc, this->account)
+        {
+            acc->serialize(writer);
+        }
+
+        if (!this->privileges.isEmpty()) {
+            this->privileges.serialize(writer);
+        }
+    }
+    endElement(writer);
+}
+
+void Author::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "author");
+    writeAttribute(writer, "email", this->email, !this->email.empty());
+    writeAttribute(writer, "href", this->href, !this->href.empty());
+    writeAttribute(writer, "xml:lang", this->lang, !this->lang.empty());
+    writeText(writer, body);
+    endElement(writer);
+}
+
+void ServiceApplication::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "service-application");
+    writeAttribute(writer, "appid", this->appid);
+    writeAttribute(writer, "auto-restart",
+                   (!this->autoRestart.IsNull() &&
+                    (*this->autoRestart)) ? "true" :
+                   "false");
+    writeAttribute(writer, "exec", this->exec);
+    writeAttribute(writer, "on-boot", (!this->onBoot.IsNull() &&
+                                       (*this->onBoot)) ? "true" : "false");
+    writeAttribute(writer, "type", this->type);
+    FOREACH(l, this->label)
+    {
+        writeElementWithOneAttribute(writer, "label",
+                                     l->getString(), "xml:lang",
+                                     l->getLang(), l->hasLang());
+    }
+    FOREACH(i, this->icon)
+    {
+        writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang",
+                                     i->getLang(), i->hasLang());
+    }
+    FOREACH(a, this->appControl)
+    {
+        a->serialize(writer);
+    }
+    endElement(writer);
+}
+
+void UiApplication::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "ui-application");
+    writeAttribute(writer, "appid", this->appid);
+    writeAttribute(writer, "exec", this->exec);
+    if (!this->multiple.IsNull()) {
+        writeAttribute(writer, "multiple", (*this->multiple) ? "true" : "false");
+    }
+    if (!this->nodisplay.IsNull()) {
+        writeAttribute(writer,
+                       "nodisplay",
+                       (*this->nodisplay) ? "true" : "false");
+    }
+    if (!this->taskmanage.IsNull()) {
+        writeAttribute(writer,
+                       "taskmanage",
+                       (*this->taskmanage) ? "true" : "false");
+    }
+    writeAttribute(writer, "type", this->type);
+    writeAttribute(writer, "extraid", this->extraid);
+    if (!this->categories.IsNull()) {
+        writeAttribute(writer, "categories", (*this->categories));
+    }
+    FOREACH(l, this->label)
+    {
+        writeElementWithOneAttribute(writer, "label",
+                                     l->getString(), "xml:lang",
+                                     l->getLang(), l->hasLang());
+    }
+    FOREACH(i, this->icon)
+    {
+        writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang",
+                                     i->getLang(), i->hasLang());
+    }
+    FOREACH(a, this->appControl)
+    {
+        a->serialize(writer);
+    }
+    FOREACH(c, this->appCategory)
+    {
+        startElement(writer, "category");
+        writeAttribute(writer, "name", *c);
+        endElement(writer);
+    }
+    FOREACH(m, this->metadata) {
+        m->serialize(writer);
+    }
+    endElement(writer);
+}
+
+void ImeApplication::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "ime-application");
+    writeAttribute(writer, "appid", this->appid);
+    writeAttribute(writer, "exec", this->exec);
+    if (!this->multiple.IsNull()) {
+        writeAttribute(writer, "multiple", (*this->multiple) ? "true" : "false");
+    }
+    if (!this->nodisplay.IsNull()) {
+        writeAttribute(writer,
+                       "nodisplay",
+                       (*this->nodisplay) ? "true" : "false");
+    }
+    writeAttribute(writer, "type", this->type);
+    FOREACH(l, this->label)
+    {
+        writeElementWithOneAttribute(writer, "label",
+                                     l->getString(), "xml:lang",
+                                     l->getLang(), l->hasLang());
+    }
+    FOREACH(i, this->icon)
+    {
+        writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang",
+                                     i->getLang(), i->hasLang());
+    }
+    endElement(writer);
+}
+
+void AppControl::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "app-control");
+    FOREACH(o, this->operation)
+    {
+        startElement(writer, "operation");
+        writeAttribute(writer, "name", *o);
+        endElement(writer);
+    }
+    FOREACH(u, this->uri)
+    {
+        startElement(writer, "uri");
+        writeAttribute(writer, "name", *u);
+        endElement(writer);
+    }
+    FOREACH(m, this->mime)
+    {
+        startElement(writer, "mime");
+        writeAttribute(writer, "name", *m);
+        endElement(writer);
+    }
+    endElement(writer);
+}
+
+void LiveBox::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "livebox");
+    if (!this->liveboxId.empty()) {
+        writeAttribute(writer, "appid", this->liveboxId);
+    }
+
+    if (!this->primary.empty()) {
+        writeAttribute(writer, "primary", this->primary);
+    }
+
+    if (!this->updatePeriod.empty()) {
+        writeAttribute(writer, "period", this->updatePeriod);
+    }
+
+    writeAttribute(writer, "abi", "html");
+    writeAttribute(writer, "network", "true");
+    writeAttribute(writer, "nodisplay", "false");
+
+    if (!this->label.empty()) {
+        int defaultLabelChk = 0;
+        FOREACH(m, this->label)
+        {
+            std::pair<DPL::String, DPL::String> boxLabel = *m;
+            startElement(writer, "label");
+            if (!boxLabel.first.empty()) {
+                writeAttribute(writer, "xml:lang", boxLabel.first);
+            } else {
+                defaultLabelChk++;
+            }
+            writeText(writer, boxLabel.second);
+            endElement(writer);
+        }
+        if(!defaultLabelChk) {
+            startElement(writer, "label");
+            writeText(writer, DPL::FromUTF8String("NO NAME"));
+            endElement(writer);
+        }
+    }
+    if (!this->icon.empty()) {
+        startElement(writer, "icon");
+        writeText(writer, this->icon);
+        endElement(writer);
+    }
+
+    if (!this->autoLaunch.empty()) {
+        startElement(writer, "launch");
+        writeText(writer, this->autoLaunch);
+        endElement(writer);
+    }
+
+    if (!this->box.boxSrc.empty() &&
+        !this->box.boxMouseEvent.empty() &&
+        !this->box.boxSize.empty())
+    {
+        startElement(writer, "box");
+        writeAttribute(writer, "type", "buffer");
+        writeAttribute(writer, "mouse_event", this->box.boxMouseEvent);
+        writeAttribute(writer, "touch_effect", this->box.boxTouchEffect);
+
+        FOREACH(it, this->box.boxSize)
+        {
+            startElement(writer, "size");
+            if (!(*it).m_preview.empty()) {
+                writeAttribute(writer, "preview", (*it).m_preview);
+            }
+            if (!(*it).m_useDecoration.empty()) {
+                writeAttribute(writer, "need_frame", (*it).m_useDecoration);
+            } else {
+                // default value of use-decoration is "true"
+                writeAttribute(writer, "need_frame", DPL::String(L"true"));
+            }
+
+            writeText(writer, (*it).m_size);
+            endElement(writer);
+        }
+
+        startElement(writer, "script");
+        writeAttribute(writer, "src", this->box.boxSrc);
+        endElement(writer);
+
+        endElement(writer);
+
+        if (!this->box.pdSrc.empty() &&
+            !this->box.pdWidth.empty() &&
+            !this->box.pdHeight.empty())
+        {
+            startElement(writer, "pd");
+            writeAttribute(writer, "type", "buffer");
+
+            startElement(writer, "size");
+            DPL::String pdSize = this->box.pdWidth + DPL::String(L"x") +
+                this->box.pdHeight;
+            writeText(writer, pdSize);
+            endElement(writer);
+
+            startElement(writer, "script");
+            writeAttribute(writer, "src", this->box.pdSrc);
+            endElement(writer);
+
+            endElement(writer);
+        }
+    }
+
+    endElement(writer);
+}
+
+void Account::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "account");
+    {
+        startElement(writer, "account-provider");
+        writeAttribute(writer, "appid", this->provider.appid);
+        writeAttribute(writer, "multiple-accounts-support",
+                this->provider.multiAccount);
+
+        FOREACH(i, this->provider.icon)
+        {
+            startElement(writer, "icon");
+            writeAttribute(writer, "section", i->first);
+            writeText(writer, i->second);
+            endElement(writer);
+        }
+
+        bool setDefaultLang = false;
+        FOREACH(n, this->provider.name)
+        {
+            if (!setDefaultLang && n->getLang() == L"en-gb") {
+                writeElement(writer, "label", n->getString());
+                setDefaultLang = true;
+            }
+            writeElementWithOneAttribute(writer, "label",
+                    n->getString(), "xml:lang",
+                    n->getLang(), n->hasLang());
+        }
+        if (!setDefaultLang) {
+            writeElement(writer, "label", this->provider.name.begin()->getString());
+        }
+
+        FOREACH(c, this->provider.capability)
+        {
+            startElement(writer, "capability");
+            writeText(writer, *c);
+            endElement(writer);
+        }
+        endElement(writer);
+    }
+    endElement(writer);
+}
+
+void Privilege::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "privileges");
+    {
+        FOREACH(it, this->name)
+        {
+            startElement(writer, "privilege");
+            writeText(writer, *it);
+            endElement(writer);
+        }
+    }
+    endElement(writer);
+}
+
+void Metadata::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "metadata");
+    writeAttribute(writer, "key", *this->key);
+    if (!this->value.IsNull()) {
+        writeAttribute(writer, "value", *this->value);
+    }
+    endElement(writer);
+}
+} //namespace Jobs
+} //namespace WidgetInstall
diff --git a/src_mobile/jobs/widget_install/manifest.h b/src_mobile/jobs/widget_install/manifest.h
new file mode 100644 (file)
index 0000000..67ee3ce
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2012 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    manifest.h
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ */
+
+#ifndef INSTALLER_JOBS_MANIFEST_H
+#define INSTALLER_JOBS_MANIFEST_H
+
+#include <list>
+
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+#include <dpl/string.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+/**
+ * @brief string with optional language attribute
+ */
+class StringWithLang
+{
+  public:
+    StringWithLang() { }
+    StringWithLang(DPL::String s) : string(s) { }
+    StringWithLang(DPL::String s, DPL::String l) : string(s), lang(l) { }
+    DPL::String getString()
+    {
+        return this->string;
+    }
+    DPL::String getLang()
+    {
+        return this->lang;
+    }
+    bool hasLang()
+    {
+        return !this->lang.empty();
+    }
+    int operator==(const StringWithLang &other)
+    {
+        return (DPL::ToUTF8String(other.string) == DPL::ToUTF8String(string)) &&
+               (DPL::ToUTF8String(other.lang) == DPL::ToUTF8String(lang));
+    }
+
+  private:
+    DPL::String string;
+    DPL::String lang;
+};
+
+typedef StringWithLang LabelType, IconType, DescriptionType;
+
+/**
+ * These types are basicaly strings but they should allow usage of different
+ * range of characters or words (details in XML spec.).
+ * For simplicity DPL::Strings are used, although this can lead to XML
+ * validation
+ * errors (related to usage of not allowed characters in given places).
+ */
+typedef DPL::String NcnameType, NmtokenType, AnySimpleType, LangType;
+typedef DPL::String OperationType, MimeType, UriType, TypeType, PackageType;
+typedef DPL::OptionalString InstallLocationType, CategoriesType;
+typedef DPL::String AppCategoryType;
+typedef DPL::OptionalString KeyType, ValueType;
+
+/**
+ * xmllib2 wrappers
+ */
+void writeElement(xmlTextWriterPtr writer, const char * name, DPL::String body);
+void writeText(xmlTextWriterPtr writer, DPL::String text);
+void writeElement(xmlTextWriterPtr writer, const char * name, const char * body);
+void writeElementWithOneAttribute(xmlTextWriterPtr writer,
+                                  const char * name,
+                                  const char * body,
+                                  const char * nameAttr,
+                                  DPL::String bodyAttr,
+                                  bool condition = true);
+void startElement(xmlTextWriterPtr writer, const char * name);
+void endElement(xmlTextWriterPtr writer);
+void writeAttribute(xmlTextWriterPtr writer, const char * name,
+                    DPL::String body, bool condition);
+void writeAttribute(xmlTextWriterPtr writer, const char * name,
+                    const char * body, bool condition);
+
+/**
+ * @brief author element
+ */
+class Author
+{
+  public:
+    Author() {}
+    Author(AnySimpleType e,
+           NcnameType h,
+           LangType l,
+           DPL::String b) :
+        email(e), href(h), lang(l), body(b) {}
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    AnySimpleType email;
+    NcnameType href;
+    LangType lang;
+    DPL::String body;
+};
+
+typedef Author AuthorType;
+
+/**
+ * @brief application-service element
+ */
+class AppControl
+{
+  public:
+    AppControl() {}
+    void addOperation(const OperationType &x)
+    {
+        this->operation.push_back(x);
+    }
+    void addUri(const UriType &x)
+    {
+        this->uri.push_back(x);
+    }
+    void addMime(const MimeType &x)
+    {
+        this->mime.push_back(x);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    std::list<OperationType> operation; //attr name AnySimpleType
+    std::list<UriType> uri; //attr name AnySimpleType
+    std::list<MimeType> mime; //attr name AnySimpleType
+};
+
+typedef AppControl AppControlType;
+
+/**
+ * @brief account element
+ */
+typedef std::list<std::pair<DPL::String, DPL::String>> IconListType;
+typedef std::list<LabelType> DisplayNameListType;
+typedef std::list<DPL::String> AccountCapabilityType;
+
+struct AccountProvider
+{
+    NcnameType appid;
+    NcnameType multiAccount;
+    IconListType icon;
+    DisplayNameListType name;
+    AccountCapabilityType capability;
+};
+
+typedef AccountProvider AccountProviderType;
+
+class Account
+{
+  public:
+    Account() {}
+    void addAccountProvider(const AccountProvider &x)
+    {
+        this->provider = x;
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    AccountProviderType provider;
+};
+
+class Privilege
+{
+  public:
+    Privilege() {}
+    void addPrivilegeName(const DPL::String &x)
+    {
+        this->name.push_back(x);
+    }
+    bool isEmpty()
+    {
+        return this->name.empty();
+    }
+
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    std::list<DPL::String> name;
+};
+
+typedef Privilege PrivilegeType;
+
+class Metadata
+{
+  public:
+    Metadata(KeyType k, ValueType v) :
+        key(k),
+        value(v)
+    {}
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    KeyType key;
+    ValueType value;
+};
+
+typedef Metadata MetadataType;
+
+
+/**
+ * @brief ime-application element
+ */
+class ImeApplication
+{
+  public:
+    ImeApplication() {}
+    void setAppid(const NcnameType &x)
+    {
+        this->appid = x;
+    }
+    void setExec(const NcnameType &x)
+    {
+        this->exec = x;
+    }
+    void setMultiple(bool x)
+    {
+        this->multiple = x;
+    }
+    void setNodisplay(bool x)
+    {
+        this->nodisplay = x;
+    }
+    void setType(const TypeType &x)
+    {
+        this->type = x;
+    }
+    void addLabel(const LabelType &x)
+    {
+        this->label.push_back(x);
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    NcnameType appid;
+    NcnameType exec;
+    DPL::OptionalBool multiple;
+    DPL::OptionalBool nodisplay;
+    TypeType type;
+    std::list<LabelType> label;
+    std::list<IconType> icon;
+};
+
+typedef ImeApplication ImeApplicationType;
+
+/**
+ * @brief service-application element
+ */
+class ServiceApplication
+{
+  public:
+    ServiceApplication() {}
+    void setAppid(const NcnameType &x)
+    {
+        this->appid = x;
+    }
+    void setAutoRestart(bool x)
+    {
+        this->autoRestart = x;
+    }
+    void setExec(const AnySimpleType &x)
+    {
+        this->exec = x;
+    }
+    void setOnBoot(bool x)
+    {
+        this->onBoot = x;
+    }
+    void setType(const TypeType &x)
+    {
+        this->type = x;
+    }
+    void addLabel(const LabelType &x)
+    {
+        this->label.push_back(x);
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void addAppControl(const AppControlType &x)
+    {
+        this->appControl.push_back(x);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    NcnameType appid;
+    DPL::OptionalBool autoRestart;
+    AnySimpleType exec;
+    DPL::OptionalBool onBoot;
+    TypeType type;
+    std::list<LabelType> label; //attr name AnySimpleType
+    std::list<IconType> icon; //attr name AnySimpleType
+    std::list<AppControlType> appControl; //attr name AnySimpleType
+};
+
+typedef ServiceApplication ServiceApplicationType;
+
+/**
+ * @brief ui-application element
+ */
+class UiApplication
+{
+  public:
+    UiApplication() {}
+    void setAppid(const NcnameType &x)
+    {
+        this->appid = x;
+    }
+    void setExtraid(const NcnameType &x)
+    {
+        this->extraid = x;
+    }
+    void setExec(const AnySimpleType &x)
+    {
+        this->exec = x;
+    }
+    void setMultiple(bool x)
+    {
+        this->multiple = x;
+    }
+    void setNodisplay(bool x)
+    {
+        this->nodisplay = x;
+    }
+    void setTaskmanage(bool x)
+    {
+        this->taskmanage = x;
+    }
+    void setType(const TypeType &x)
+    {
+        this->type = x;
+    }
+    void setCategories(const NcnameType &x)
+    {
+        this->categories = x;
+    }
+    void addLabel(const LabelType &x)
+    {
+        this->label.push_back(x);
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void addAppControl(const AppControlType &x)
+    {
+        this->appControl.push_back(x);
+    }
+    void addAppCategory(const AppCategoryType &x)
+    {
+        this->appCategory.push_back(x);
+    }
+    void addMetadata(const MetadataType &m)
+    {
+        this->metadata.push_back(m);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    NcnameType appid;
+    NcnameType extraid;
+    AnySimpleType exec;
+    DPL::OptionalBool multiple;
+    DPL::OptionalBool nodisplay;
+    DPL::OptionalBool taskmanage;
+    TypeType type;
+    CategoriesType categories;
+    std::list<LabelType> label;
+    std::list<IconType> icon;
+    std::list<AppControlType> appControl;
+    std::list<AppCategoryType> appCategory;
+    std::list<MetadataType> metadata;
+};
+
+typedef UiApplication UiApplicationType;
+
+/**
+ * @brief LiveBox element
+ */
+typedef WrtDB::ConfigParserData::LiveboxInfo::BoxSizeList BoxSizeType;
+typedef WrtDB::ConfigParserData::LiveboxInfo::BoxLabelList BoxLabelType;
+
+struct BoxInfo
+{
+    NcnameType boxSrc;
+    NcnameType boxMouseEvent;
+    NcnameType boxTouchEffect;
+    BoxSizeType boxSize;
+    NcnameType pdSrc;
+    NcnameType pdWidth;
+    NcnameType pdHeight;
+};
+typedef BoxInfo BoxInfoType;
+
+class LiveBox
+{
+  public:
+    LiveBox() { }
+    void setLiveboxId(const NcnameType &x)
+    {
+        this->liveboxId = x;
+    }
+    void setPrimary(const NcnameType &x)
+    {
+        this->primary = x;
+    }
+    void setUpdatePeriod(const NcnameType &x)
+    {
+        this->updatePeriod = x;
+    }
+    void setLabel(const BoxLabelType &x)
+    {
+        this->label = x;
+    }
+    void setIcon(const NcnameType &x)
+    {
+        this->icon = x;
+    }
+    void setBox(const BoxInfoType &x)
+    {
+        this->box = x;
+    }
+
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    NcnameType liveboxId;
+    NcnameType primary;
+    NcnameType autoLaunch;
+    NcnameType updatePeriod;
+    NcnameType timeout;
+    BoxLabelType label;
+    NcnameType icon;
+    NcnameType lang;
+    BoxInfoType box;
+};
+
+typedef LiveBox LiveBoxInfo;
+
+/**
+ * @brief manifest element
+ *
+ * Manifest xml file representation.
+ */
+class Manifest
+{
+  public:
+    Manifest() {}
+    void serialize(xmlTextWriterPtr writer);
+    void generate(DPL::String filename);
+
+    void addLabel(const LabelType &x)
+    {
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+        auto pos = std::find(label.begin(), label.end(), x);
+        if (pos == label.end()) {
+            this->label.push_back(x);
+        }
+#else
+        this->label.push_back(x);
+#endif
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void addAuthor(const AuthorType &x)
+    {
+        this->author.push_back(x);
+    }
+    void addDescription(const DescriptionType &x)
+    {
+        this->description.push_back(x);
+    }
+    //    void addCompatibility(const CompatibilityType &x)
+    //    {
+    //        this->compatibility.push_back(x);
+    //    }
+    //    void addDeviceProfile(const DeviceProfileType &x)
+    //    {
+    //        this->deviceProfile.push_back(x);
+    //    }
+    void addServiceApplication(const ServiceApplicationType &x)
+    {
+        this->serviceApplication.push_back(x);
+    }
+    void addUiApplication(const UiApplicationType &x)
+    {
+        this->uiApplication.push_back(x);
+    }
+    void addImeApplication(const ImeApplicationType &x)
+    {
+        this->imeApplication.push_back(x);
+    }
+    //    void addFont(const FontType &x) { this->font.push_back(x); }
+
+    void addLivebox(const LiveBoxInfo &x)
+    {
+        this->livebox.push_back(x);
+    }
+
+    void addAccount(const Account &x)
+    {
+        this->account.push_back(x);
+    }
+
+    void addPrivileges(const PrivilegeType &x)
+    {
+        this->privileges = x;
+    }
+
+    void setInstallLocation(const InstallLocationType &x)
+    {
+        this->installLocation = x;
+    }
+    void setPackage(const NcnameType &x)
+    {
+        this->package = x;
+    }
+    void setType(const PackageType &x)
+    {
+        this->type = x;
+    }
+    void setVersion(const NmtokenType &x)
+    {
+        this->version = x;
+    }
+    void setStoreClientId(const NcnameType &x)
+    {
+        this->storeClientId= x;
+    }
+
+  private:
+    std::list<LabelType> label;
+    std::list<IconType> icon;
+    std::list<AuthorType> author;
+    std::list<DescriptionType> description;
+    //    std::list<CompatibilityType> compatibility;
+    //    std::list<DeviceProfileType> deviceProfile;
+    std::list<ServiceApplicationType> serviceApplication;
+    std::list<UiApplicationType> uiApplication;
+    std::list<ImeApplicationType> imeApplication;
+    //    std::list<FontType> font;
+    std::list<LiveBoxInfo> livebox;
+    InstallLocationType installLocation;
+    NcnameType package;
+    PackageType type;
+    NmtokenType version;
+    std::list<Account> account;
+    PrivilegeType privileges;
+    NcnameType storeClientId;
+
+};
+} //namespace Jobs
+} //namespace WidgetInstall
+
+#endif //INSTALLER_JOBS_MANIFEST_H
diff --git a/src_mobile/jobs/widget_install/task_ace_check.cpp b/src_mobile/jobs/widget_install/task_ace_check.cpp
new file mode 100644 (file)
index 0000000..cf44fc0
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * 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 <utility>
+#include <vector>
+#include <string>
+
+#include <widget_install/task_ace_check.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/job_widget_install.h>
+
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <ace_api_install.h>
+
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskAceCheck::TaskAceCheck(InstallerContext& context) :
+    DPL::TaskDecl<TaskAceCheck>(this),
+    m_context(context)
+{
+    AddStep(&TaskAceCheck::StartStep);
+    AddStep(&TaskAceCheck::StepPrepareForAce);
+    AddStep(&TaskAceCheck::StepAceCheck);
+    AddStep(&TaskAceCheck::StepProcessAceResponse);
+    AddStep(&TaskAceCheck::StepCheckAceResponse);
+    AddStep(&TaskAceCheck::EndStep);
+}
+
+void TaskAceCheck::StepPrepareForAce()
+{
+    m_context.featureLogic =
+        FeatureLogicPtr(new FeatureLogic(m_context.widgetConfig.tzAppid));
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_ACE_PREPARE,
+        "Widget Access Control Check Prepared");
+}
+
+void TaskAceCheck::StepAceCheck()
+{
+    WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
+    _D("StepAceCheck!");
+    // This widget does not use any device cap
+    if (m_context.featureLogic->isDone()) {
+        return;
+    }
+
+    _D("StepAceCheck!");
+    DPL::String deviceCap = m_context.featureLogic->getDevice();
+
+    _D("StepAceCheck!");
+    _D("DevCap is : %ls", deviceCap.c_str());
+
+    std::string devCapStr = DPL::ToUTF8String(deviceCap);
+    ace_policy_result_t policyResult = ACE_DENY;
+
+    //TODO: remove dao.getHandle()
+    if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
+        _D("This widget is preloaded. So ace check will be skiped");
+        policyResult = ACE_PERMIT;
+    } else {
+        ace_return_t ret = ace_get_policy_result(
+                const_cast<const ace_resource_t>(devCapStr.c_str()),
+                dao.getHandle(),
+                &policyResult);
+        if (ACE_OK != ret) {
+            ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
+                    "ACE check failure");
+        }
+    }
+
+    _D("PolicyResult is : %d", static_cast<int>(policyResult));
+    m_context.staticPermittedDevCaps.insert(std::make_pair(deviceCap,
+                                                           policyResult ==
+                                                           ACE_PERMIT));
+
+    m_context.featureLogic->setAceResponse(policyResult != ACE_DENY);
+}
+
+void TaskAceCheck::StepProcessAceResponse()
+{
+    WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
+    if (m_context.widgetConfig.packagingType ==
+        WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+    {
+        return;
+    }
+
+    _D("StepProcessAceResponse");
+    m_context.featureLogic->next();
+
+    // No device caps left to process
+    if (m_context.featureLogic->isDone()) {
+        _D("All responses has been received from ACE.");
+        // Data to convert to C API
+        std::vector<std::string> devCaps;
+        std::vector<bool> devCapsSmack;
+        // Saving static dev cap permissions
+        FOREACH(cap, m_context.staticPermittedDevCaps) {
+            _D("staticPermittedDevCaps : %ls smack: %d", cap->first.c_str(), cap->second);
+            std::string devCapStr = DPL::ToUTF8String(cap->first);
+            devCaps.push_back(devCapStr);
+            devCapsSmack.push_back(cap->second);
+        }
+        ace_requested_dev_cap_list_t list;
+        list.count = devCaps.size();
+        list.items = new ace_requested_dev_cap_t[list.count];
+
+        for (unsigned int i = 0; i < devCaps.size(); ++i) {
+            list.items[i].device_capability =
+                const_cast<const ace_resource_t>(devCaps[i].c_str());
+            list.items[i].smack_granted =
+                devCapsSmack[i] ? ACE_TRUE : ACE_FALSE;
+        }
+        //TODO: remove dao.getHandle()
+        ace_return_t ret = ace_set_requested_dev_caps(dao.getHandle(),
+                                                      &list);
+        if (ACE_OK != ret) {
+            ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
+                                             "ACE failure");
+        }
+        delete[] list.items;
+
+        std::set<std::string> acceptedFeature;
+        auto it = m_context.featureLogic->resultBegin();
+        for (; it != m_context.featureLogic->resultEnd(); ++it) {
+            if (!(it->rejected)) {
+                acceptedFeature.insert(DPL::ToUTF8String(it->name));
+            }
+        }
+        ace_feature_list_t featureList;
+        featureList.count = acceptedFeature.size();
+        featureList.items = new ace_string_t[featureList.count];
+
+        size_t i = 0;
+        for (std::set<std::string>::const_iterator iter = acceptedFeature.begin();
+             iter != acceptedFeature.end(); ++iter)
+        {
+            _D("Accepted feature item: %s", iter->c_str());
+            featureList.items[i] = const_cast<char *>(iter->c_str());
+            i++;
+        }
+
+        //TODO: remove dao.getHandle()
+        ret = ace_set_accepted_feature(dao.getHandle(), &featureList);
+
+        delete[] featureList.items;
+
+        if (ACE_OK != ret) {
+            _E("Error in ace_set_feature");
+            ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
+                                             "ace_set_feature failure.");
+        }
+        return;
+    }
+
+    _D("Next device cap.");
+    // Process next device cap
+    SwitchToStep(&TaskAceCheck::StepAceCheck);
+}
+
+void TaskAceCheck::StepCheckAceResponse()
+{
+    _D("Checking ACE response");
+    if (m_context.featureLogic->isRejected()) {
+        _E("Installation failure. Some devCap was not accepted by ACE.");
+        ThrowMsg(
+            Exceptions::PrivilegeLevelViolation,
+            "Instalation failure. "
+            "Some deviceCap was not accepted by ACE.");
+    }
+    _D("Updating \"feature reject status\" in database!");
+    auto it = m_context.featureLogic->resultBegin();
+    auto end = m_context.featureLogic->resultEnd();
+    for (; it != end; ++it) {
+        _D("  |-  Feature: %ls has reject status: %d", it->name.c_str(), it->rejected);
+        if (it->rejected) {
+            WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
+            dao.updateFeatureRejectStatus(*it);
+        }
+    }
+    _D("Installation continues...");
+}
+
+void TaskAceCheck::StartStep()
+{
+    _D("--------- <TaskAceCheck> : START ----------");
+}
+
+void TaskAceCheck::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_ACE_CHECK,
+        "Widget Access Control Check Finished");
+
+    _D("--------- <TaskAceCheck> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_ace_check.h b/src_mobile/jobs/widget_install/task_ace_check.h
new file mode 100644 (file)
index 0000000..e4ce90d
--- /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    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>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskAceCheck :
+    public DPL::TaskDecl<TaskAceCheck>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StepPrepareForAce();
+    void StepAceCheck();
+    void StepProcessAceResponse();
+    void StepCheckAceResponse();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskAceCheck(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_ACE_CHECK_H */
diff --git a/src_mobile/jobs/widget_install/task_certify.cpp b/src_mobile/jobs/widget_install/task_certify.cpp
new file mode 100644 (file)
index 0000000..81f21b0
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * 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 <sstream>
+#include <unistd.h>
+#include <dpl/assert.h>
+#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/wrt-dao-ro/global_config.h>
+#include "wac_widget_id.h"
+
+#include <vcore/Certificate.h>
+#include <vcore/SignatureReader.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/WrtSignatureValidator.h>
+#include <dpl/utils/wrt_global_settings.h>
+
+#include <ITapiModem.h>
+#include <tapi_common.h>
+
+#include <installer_log.h>
+
+using namespace ValidationCore;
+using namespace WrtDB;
+
+namespace {
+
+WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
+                                              bool root)
+{
+    WidgetCertificateData result;
+
+    result.chainId = data.getSignatureNumber();
+    _D("result.chainId : %d", result.chainId);
+
+    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 && !certificate->getCommonName().IsNull() &&
+           "CommonName is Null");
+
+    result.strCommonName = *certificate->getCommonName();
+
+    result.strMD5Fingerprint = std::string("md5 ") +
+        Certificate::FingerprintToColonHex(
+            certificate->getFingerprint(Certificate::FINGERPRINT_MD5));
+
+    result.strSHA1Fingerprint = std::string("sha-1 ") +
+        Certificate::FingerprintToColonHex(
+            certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
+
+    return result;
+}
+
+CertificatePtr getOldAuthorSignerCertificate(DPL::String appid)
+{
+    WidgetDAOReadOnly dao(appid);
+    CertificateChainList chainList = dao.getWidgetCertificate(SIGNATURE_AUTHOR);
+
+    FOREACH(it, chainList)
+    {
+        ValidationCore::CertificateCollection chain;
+        if (false == chain.load(*it)) {
+            _E("Chain is broken");
+        }
+
+        if (!chain.sort()) {
+            _E("Chain failed at sorting");
+        }
+
+        ValidationCore::CertificateList list = chain.getCertificateList();
+
+        FOREACH(cert, list)
+        {
+            if (!(*cert)->isRootCert() && !(*cert)->isCA()) {
+                return *cert;
+            }
+        }
+    }
+    return CertificatePtr(NULL);
+}
+} // namespace anonymous
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskCertify::TaskCertify(InstallerContext &inCont) :
+    DPL::TaskDecl<TaskCertify>(this),
+    m_contextData(inCont)
+{
+    AddStep(&TaskCertify::StartStep);
+    AddStep(&TaskCertify::stepSignature);
+    // certi comparison determines whether the update.
+    if (true == m_contextData.isUpdateMode) {
+        AddStep(&TaskCertify::stepVerifyUpdate);
+    }
+    AddStep(&TaskCertify::EndStep);
+}
+
+void TaskCertify::processDistributorSignature(const SignatureData &data)
+{
+    // this signature is verified -
+    // no point in check domain WAC_ROOT and WAC_RECOGNIZED
+    m_contextData.widgetSecurity.setDistributorSigned(true);
+
+    CertificateCollection collection;
+    collection.load(data.getCertList());
+    Assert(collection.sort() &&
+           "Certificate collection can't sort");
+
+    Assert(collection.isChain() &&
+           "Certificate collection is not able to create chain. "
+           "It is not possible to verify this signature.");
+
+    m_contextData.widgetSecurity.getCertificateChainListRef().push_back(
+        collection);
+
+    if (data.getSignatureNumber() == 1) {
+        m_contextData.widgetSecurity.getCertificateListRef().push_back(
+            toWidgetCertificateData(data, true));
+        m_contextData.widgetSecurity.getCertificateListRef().push_back(
+            toWidgetCertificateData(data, false));
+    }
+}
+
+void TaskCertify::processAuthorSignature(const SignatureData &data)
+{
+    using namespace ValidationCore;
+    _D("DNS Identity match!");
+    // this signature is verified or widget is distributor signed
+    m_contextData.widgetSecurity.setAuthorCertificatePtr(data.getEndEntityCertificatePtr());
+    CertificatePtr test = m_contextData.widgetSecurity.getAuthorCertificatePtr();
+
+    m_contextData.widgetSecurity.getCertificateListRef().push_back(
+        toWidgetCertificateData(data, true));
+    m_contextData.widgetSecurity.getCertificateListRef().push_back(
+        toWidgetCertificateData(data, false));
+
+    // match widget_id with one from dns identity set
+    WacWidgetId widgetId(m_contextData.widgetConfig.configInfo.widget_id);
+
+    CertificatePtr cert = data.getEndEntityCertificatePtr();
+    Assert(cert);
+    Certificate::AltNameSet dnsIdentity = cert->getAlternativeNameDNS();
+
+    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.widgetSecurity.getAuthorsCertificateChainListRef().push_back(
+        collection);
+
+    FOREACH(it, dnsIdentity){
+        if (widgetId.matchHost(*it)) {
+            m_contextData.widgetSecurity.setRecognized(true);
+            return;
+        }
+    }
+}
+
+void TaskCertify::getSignatureFiles(std::string path, SignatureFileInfoSet& file)
+{
+    _D("path : %s", path.c_str());
+    SignatureFileInfoSet signatureFiles;
+    SignatureFinder signatureFinder(path);
+    if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
+        _E("Error in Signature Finder : %s", path.c_str());
+        ThrowMsg(Exceptions::SignatureNotFound,
+                "Error openig temporary widget directory");
+    }
+}
+
+void TaskCertify::stepSignature()
+{
+    _D("================ Step: <<Signature>> ENTER ===============");
+
+    std::string widgetPath;
+    widgetPath = m_contextData.locations->getPackageInstallationDir() + "/";
+
+    SignatureFileInfoSet signatureFiles;
+
+    Try {
+        getSignatureFiles(widgetPath, signatureFiles);
+
+        if (signatureFiles.size() <= 0) {
+            widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
+                + "/";
+            if (0 == access(widgetPath.c_str(), F_OK)) {
+                getSignatureFiles(widgetPath, signatureFiles);
+            }
+        }
+    } Catch(Exceptions::SignatureNotFound) {
+        ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
+    }
+
+    SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
+    _D("Number of signatures: %d", signatureFiles.size());
+
+    for (; iter != signatureFiles.rend(); ++iter) {
+        _D("Checking signature with id=%d", iter->getFileNumber());
+        SignatureData data(widgetPath + iter->getFileName(),
+                           iter->getFileNumber());
+
+        Try {
+            SignatureReader xml;
+            xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
+            xml.read(data);
+
+            WrtSignatureValidator::Result result;
+
+            WrtSignatureValidator validator(
+                    WrtSignatureValidator::TIZEN,
+                    !GlobalSettings::
+                    OCSPTestModeEnabled(),
+                    !GlobalSettings::
+                    CrlTestModeEnabled(),
+                    false);
+
+            result = validator.check(data, widgetPath);
+
+            if (m_contextData.mode.installTime
+                ==  InstallMode::InstallTime::PRELOAD)
+            {
+                result = WrtSignatureValidator::SIGNATURE_VERIFIED;
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
+                _W("Certificate is REVOKED");
+                ThrowMsg(Exceptions::CertificateExpired,
+                         "Certificate is REVOKED");
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
+                    iter->getFileNumber() <= 1) {
+                _W("Signature is INVALID");
+                // TODO change exception name
+                ThrowMsg(Exceptions::SignatureInvalid,
+                         "Invalid Package");
+            }
+
+            if (data.isAuthorSignature()) {
+                if (result == WrtSignatureValidator::SIGNATURE_VERIFIED ) {
+                    processAuthorSignature(data);
+                }
+            } else {
+                if (result != WrtSignatureValidator::SIGNATURE_INVALID) {
+                    processDistributorSignature(data);
+                }
+            }
+        } Catch(ParserSchemaException::Base) {
+            _E("Error occured in ParserSchema.");
+            ReThrowMsg(Exceptions::SignatureInvalid,
+                       "Error occured in ParserSchema.");
+        }
+    }
+
+    if (signatureFiles.empty()) {
+        _D("No signature files has been found.");
+    }
+
+    _D("================ Step: <<Signature>> DONE ================");
+
+    m_contextData.job->UpdateProgress(
+        InstallerContext::INSTALL_DIGSIG_CHECK,
+        "Widget Signature checked");
+}
+
+bool TaskCertify::isTizenWebApp() const
+{
+    bool ret = FALSE;
+    if (m_contextData.widgetConfig.webAppType.appType
+        == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
+    {
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+void TaskCertify::stepVerifyUpdate()
+{
+    _D("Step: <<Check Update>>");
+    CertificatePtr newCertificate =
+        m_contextData.widgetSecurity.getAuthorCertificatePtr();
+    CertificatePtr oldCertificate =
+        getOldAuthorSignerCertificate(m_contextData.widgetConfig.tzAppid);
+
+    if (!!newCertificate && !!oldCertificate) {
+        if (0 != newCertificate->getBase64().compare(oldCertificate->getBase64())) {
+            _D("old widget's author signer certificate : %s", (oldCertificate->getBase64()).c_str());
+            _D("new widget's author signer certificate : %s", (newCertificate->getBase64()).c_str());
+            ThrowMsg(Exceptions::NotMatchedCertification,
+                    "Author signer certificates doesn't match \
+                    between old widget and installing widget");
+        }
+    } else {
+        if (!(NULL == newCertificate.Get() && NULL == oldCertificate.Get())) {
+            ThrowMsg(Exceptions::NotMatchedCertification,
+                    "Author signer certificates doesn't match \
+                    between old widget and installing widget");
+        }
+    }
+}
+
+void TaskCertify::StartStep()
+{
+    _D("--------- <TaskCertify> : START ----------");
+}
+
+void TaskCertify::EndStep()
+{
+    _D("Step: <<CERTYFYING DONE>>");
+
+    m_contextData.job->UpdateProgress(
+        InstallerContext::INSTALL_CERT_CHECK,
+        "Widget Certification Check Finished");
+
+    _D("--------- <TaskCertify> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
+
diff --git a/src_mobile/jobs/widget_install/task_certify.h b/src_mobile/jobs/widget_install/task_certify.h
new file mode 100644 (file)
index 0000000..6a59781
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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>
+#include <vcore/SignatureFinder.h>
+
+//WRT INCLUDES
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace ValidationCore {
+class SignatureData;
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskCertify :
+    public DPL::TaskDecl<TaskCertify>
+{
+  public:
+    TaskCertify(InstallerContext &inCont);
+
+  private:
+    //data
+    InstallerContext& m_contextData;
+
+    //steps
+    void stepSignature();
+    void stepVerifyUpdate();
+
+    void StartStep();
+    void EndStep();
+
+    void processDistributorSignature(const ValidationCore::SignatureData &data);
+    void processAuthorSignature(const ValidationCore::SignatureData &data);
+    void getSignatureFiles(std::string path,
+            ValidationCore::SignatureFileInfoSet& file);
+
+    bool isTizenWebApp() const;
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_H
diff --git a/src_mobile/jobs/widget_install/task_certify_level.cpp b/src_mobile/jobs/widget_install/task_certify_level.cpp
new file mode 100644 (file)
index 0000000..9d1bc50
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2013 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_level.cpp
+ * @author  Jihoon Chung (jihoon.chung@samgsung.com)
+ * @version
+ * @brief
+ */
+
+//SYSTEM INCLUDES
+#include <string>
+#include <map>
+#include <unistd.h>
+
+//WRT INCLUDES
+#include <widget_install/task_certify_level.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/string.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <vcore/CertStoreType.h>
+#include <vcore/SignatureReader.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/WrtSignatureValidator.h>
+#include <dpl/utils/wrt_global_settings.h>
+
+#include <installer_log.h>
+
+using namespace ValidationCore;
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskCertifyLevel::TaskCertifyLevel(InstallerContext &inCont) :
+    DPL::TaskDecl<TaskCertifyLevel>(this),
+    m_contextData(inCont)
+{
+    AddStep(&TaskCertifyLevel::StartStep);
+    AddStep(&TaskCertifyLevel::stepCertifyLevel);
+    AddStep(&TaskCertifyLevel::EndStep);
+}
+
+void TaskCertifyLevel::stepCertifyLevel()
+{
+    _D("================ Step: <<Certify Level>> ENTER ===============");
+    if (!checkConfigurationLevel(getCertifyLevel())) {
+        ThrowMsg(Exceptions::PrivilegeLevelViolation, "setting level violate");
+    }
+    _D("================ Step: <<Certify Level>> DONE ================");
+}
+
+void TaskCertifyLevel::getSignatureFiles(const std::string& path,
+                                         SignatureFileInfoSet& file)
+{
+    SignatureFileInfoSet signatureFiles;
+    SignatureFinder signatureFinder(path);
+    if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
+        _E("Error in Signature Finder : %s", path.c_str());
+        ThrowMsg(Exceptions::SignatureNotFound, "Signature not found");
+    }
+}
+
+TaskCertifyLevel::Level TaskCertifyLevel::getCertifyLevel()
+{
+    std::string widgetPath = m_contextData.locations->getPackageInstallationDir() + "/";
+    SignatureFileInfoSet signatureFiles;
+
+    Try {
+        getSignatureFiles(widgetPath, signatureFiles);
+
+        if (signatureFiles.size() <= 0) {
+            widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
+                + "/";
+            if (0 == access(widgetPath.c_str(), F_OK)) {
+                getSignatureFiles(widgetPath, signatureFiles);
+            }
+        }
+    } Catch(Exceptions::SignatureNotFound) {
+        ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
+    }
+
+    SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
+    _D("Number of signatures: %d", signatureFiles.size());
+
+    Level level = Level::UNKNOWN;
+    for (; iter != signatureFiles.rend(); ++iter) {
+        _D("Checking signature with id=%d", iter->getFileNumber());
+        SignatureData data(widgetPath + iter->getFileName(),
+                           iter->getFileNumber());
+
+        Try {
+            SignatureReader xml;
+            xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
+            xml.read(data);
+
+            WrtSignatureValidator validator(
+                    WrtSignatureValidator::TIZEN,
+                    !GlobalSettings::
+                    OCSPTestModeEnabled(),
+                    !GlobalSettings::
+                    CrlTestModeEnabled(),
+                    false);
+
+            WrtSignatureValidator::Result result =
+                validator.check(data, widgetPath);
+
+            if (m_contextData.mode.installTime
+                ==  InstallMode::InstallTime::PRELOAD)
+            {
+                result = WrtSignatureValidator::SIGNATURE_VERIFIED;
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
+                ThrowMsg(Exceptions::CertificateExpired,
+                         "Certificate is REVOKED");
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
+                    iter->getFileNumber() <= 1)
+            {
+                ThrowMsg(Exceptions::SignatureInvalid, "Invalid Package");
+            }
+
+            if (data.isAuthorSignature()) {
+                _D("Skip author signature");
+            } else {
+                Level currentCertLevel =
+                    certTypeToLevel(data.getVisibilityLevel());
+                if (currentCertLevel == Level::UNKNOWN) {
+                    continue;
+                }
+                if (currentCertLevel > level) {
+                    level = currentCertLevel;
+                    _D("level %s", enumToString(level).c_str());
+                }
+            }
+        } Catch(ParserSchemaException::Base) {
+            _E("Error occured in ParserSchema.");
+            ReThrowMsg(Exceptions::SignatureInvalid,
+                       "Error occured in ParserSchema.");
+        }
+    }
+
+    m_contextData.certLevel = level;
+    return level;
+}
+
+bool TaskCertifyLevel::checkConfigurationLevel(
+    TaskCertifyLevel::Level level)
+{
+    if (!checkSettingLevel(level)) {
+        return false;
+    }
+    if (!checkAppcontrolHasDisposition(level)) {
+        return false;
+    }
+    return true;
+}
+
+bool TaskCertifyLevel::checkSettingLevel(
+    TaskCertifyLevel::Level level)
+{
+    secureSettingMap data = {
+        {"sound-mode", Level::PARTNER},
+        {"nodisplay", Level::PARTNER}
+    };
+    FOREACH(it, m_contextData.widgetConfig.configInfo.settingsList) {
+        secureSettingIter ret = data.find(DPL::ToUTF8String(it->m_name));
+        if (ret != data.end()) {
+            if (level < ret->second) {
+                _E("\"%ls\" needs \"%s\" level", it->m_name.c_str(), enumToString(ret->second).c_str());
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+bool TaskCertifyLevel::checkAppcontrolHasDisposition(
+    TaskCertifyLevel::Level level)
+{
+    // tizen:disposition -> platform
+    FOREACH(it, m_contextData.widgetConfig.configInfo.appControlList) {
+        if (ConfigParserData::AppControlInfo::Disposition::UNDEFINE !=
+            it->m_disposition)
+        {
+            if (level < Level::PLATFORM) {
+                _E("\"tizen:disposition\" needs \"%s \" level", enumToString(Level::PLATFORM).c_str());
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+std::string TaskCertifyLevel::enumToString(
+    TaskCertifyLevel::Level level)
+{
+    switch (level) {
+#define X(x, y) case x: return #y;
+        X(Level::UNKNOWN, UNKNOWN)
+        X(Level::PUBLIC, PUBLIC)
+        X(Level::PARTNER, PARTNER)
+        X(Level::PLATFORM, PLATFORM)
+#undef X
+    default:
+        return "UNKNOWN";
+    }
+}
+
+TaskCertifyLevel::Level TaskCertifyLevel::certTypeToLevel(
+    CertStoreId::Type type)
+{
+    // CertStoreType.h (framework/security/cert-svc)
+    // RootCA's visibility level : public
+    // const Type VIS_PUBLIC = 1 << 6;
+    // RootCA's visibility level : partner
+    // const Type VIS_PARTNER = 1 << 7;
+    // RootCA's visibility level : platform
+    // const Type VIS_PLATFORM = 1 << 10;
+    if (type == CertStoreId::VIS_PUBLIC) {
+        return Level::PUBLIC;
+    } else if (type == CertStoreId::VIS_PARTNER) {
+        return Level::PARTNER;
+    } else if (type == CertStoreId::VIS_PLATFORM) {
+        return Level::PLATFORM;
+    }
+    return Level::UNKNOWN;
+}
+
+void TaskCertifyLevel::StartStep()
+{
+    _D("--------- <TaskCertifyLevel> : START ----------");
+}
+
+void TaskCertifyLevel::EndStep()
+{
+    _D("--------- <TaskCertifyLevel> : END ----------");
+
+    m_contextData.job->UpdateProgress(
+        InstallerContext::INSTALL_CERTIFY_LEVEL_CHECK,
+        "Application Certificate level check Finished");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
+
diff --git a/src_mobile/jobs/widget_install/task_certify_level.h b/src_mobile/jobs/widget_install/task_certify_level.h
new file mode 100644 (file)
index 0000000..ad8d427
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013 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_level.h
+ * @author  Jihoon Chung (jihoon.chung@samgsung.com)
+ * @version
+ * @brief
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_LEVEL_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_LEVEL_H
+
+//SYSTEM INCLUDES
+#include <string>
+#include <cstdint>
+#include <map>
+
+//WRT INCLUDES
+#include <vcore/CertStoreType.h>
+#include <vcore/SignatureFinder.h>
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskCertifyLevel :
+    public DPL::TaskDecl<TaskCertifyLevel>
+{
+  public:
+    TaskCertifyLevel(InstallerContext &inCont);
+
+  private:
+    //data
+    InstallerContext& m_contextData;
+
+    enum Level {
+        UNKNOWN  = 0,
+        PUBLIC   = 1,
+        PARTNER  = 2,
+        PLATFORM = 3
+    };
+    typedef std::map<std::string, Level> secureSettingMap;
+    typedef std::map<std::string, Level>::iterator secureSettingIter;
+
+    //steps
+    void stepCertifyLevel();
+    void StartStep();
+    void EndStep();
+
+    //util
+    void getSignatureFiles(const std::string& path,
+                           ValidationCore::SignatureFileInfoSet& file);
+    Level getCertifyLevel();
+    bool checkConfigurationLevel(Level level);
+    bool checkSettingLevel(Level level);
+    bool checkAppcontrolHasDisposition(Level level);
+    std::string enumToString(Level level);
+    Level certTypeToLevel(ValidationCore::CertStoreId::Type type);
+
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_LEVEL_H
diff --git a/src_mobile/jobs/widget_install/task_commons.cpp b/src_mobile/jobs/widget_install/task_commons.cpp
new file mode 100644 (file)
index 0000000..c5b5b67
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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_commons.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include "task_commons.h"
+#include <unistd.h>
+#include <sstream>
+#include <ftw.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+#include <dpl/utils/wrt_utility.h>
+#include <widget_install/widget_install_errors.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace {
+const char * const TEMPORARY_PATH_POSTFIX = "temp";
+const mode_t TEMPORARY_PATH_MODE = 0775;
+} // namespace
+
+std::string createTempPath(bool preload)
+{
+    _D("Step: Creating temporary path");
+
+    // Temporary path
+    std::ostringstream tempPathBuilder;
+
+    if (preload) {
+        tempPathBuilder << WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+    } else {
+        tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    }
+    tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
+    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;
+
+    if (stat(tempPath.c_str(), &fileInfo) == 0) {
+        if (!WrtUtilRemove(tempPath)) {
+            ThrowMsg(Exceptions::RemovingFolderFailure,
+                     "Failed to to remove temporary directory");
+        }
+    }
+    // Create new path
+    if (!WrtUtilMakeDir(tempPath, TEMPORARY_PATH_MODE)) {
+        ThrowMsg(Exceptions::FileOperationFailed,
+                 "Failed to create temporary directory");
+    }
+
+    return tempPath;
+}
+
+void createTempPath(const std::string& path)
+{
+    if (!WrtUtilMakeDir(path, TEMPORARY_PATH_MODE)) {
+        ThrowMsg(Exceptions::FileOperationFailed,
+                 "Failed to create temporary directory");
+    }
+}
+} // WidgetInstall
+} // Jobs
diff --git a/src_mobile/jobs/widget_install/task_commons.h b/src_mobile/jobs/widget_install/task_commons.h
new file mode 100644 (file)
index 0000000..caf9660
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_commons.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_COMMONS_H_
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_COMMONS_H_
+
+#include <string>
+
+namespace Jobs {
+namespace WidgetInstall {
+//TODO make directory like jobs common?
+
+std::string createTempPath(bool isReadOnly = false);
+void createTempPath(const std::string& path);
+} // WidgetInstall
+} // Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_COMMONS_H_ */
diff --git a/src_mobile/jobs/widget_install/task_configuration.cpp b/src_mobile/jobs/widget_install/task_configuration.cpp
new file mode 100644 (file)
index 0000000..c336848
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2013 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_configuration.cpp
+ * @version 1.0
+ * @author  Tomasz Iwanek
+ * @brief   implementation file for configuration task
+ */
+#include "task_configuration.h"
+
+#include <string>
+#include <sstream>
+#include <memory>
+#include <sys/time.h>
+#include <ctime>
+#include <cstdlib>
+#include <limits.h>
+#include <regex.h>
+#include <vconf.h>
+
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/localization/w3c_file_localization.h>
+
+#include <libiriwrapper.h>
+#include <app_manager.h>
+
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install_to_external.h>
+#include <widget_install/widget_unzip.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_commons.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const char* const CONFIG_XML = "config.xml";
+const char* const WITH_OSP_XML = "res/wgt/config.xml";
+const char* const OSP_MANIFEST_XML = "info/manifest.xml";
+
+//allowed: a-z, A-Z, 0-9
+const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
+const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
+const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
+const size_t PACKAGE_ID_LENGTH = 10;
+
+static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
+static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
+static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = L"install-location";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = L"prefer-external";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_AUTO = L"auto";
+const std::string XML_EXTENSION = ".xml";
+
+bool hasExtension(const std::string& filename, const std::string& extension)
+{
+    _D("Looking for extension %s in %s", extension.c_str(), filename.c_str());
+    size_t fileLen = filename.length();
+    size_t extLen = extension.length();
+    if (fileLen < extLen) {
+        _E("Filename %s is shorter than extension %s", filename.c_str(), extension.c_str());
+        return false;
+    }
+    return (0 == filename.compare(fileLen - extLen, extLen, extension));
+}
+} // namespace anonymous
+
+namespace Jobs {
+namespace WidgetInstall {
+
+TaskConfiguration::TaskConfiguration(InstallerContext& context) :
+    DPL::TaskDecl<TaskConfiguration>(this),
+    m_context(context),
+    m_widgetConfig(m_context.widgetConfig.configInfo)
+{
+    AddStep(&TaskConfiguration::StartStep);
+
+    AddStep(&TaskConfiguration::SetupTempDirStep);
+    AddStep(&TaskConfiguration::UnzipConfigurationStep);
+    AddStep(&TaskConfiguration::ParseXMLConfigStep);
+
+    AddStep(&TaskConfiguration::TizenIdStep);
+    AddStep(&TaskConfiguration::CheckAppRunningStateStep);
+    AddStep(&TaskConfiguration::ApplicationTypeStep);
+    AddStep(&TaskConfiguration::ResourceEncryptionStep);
+    AddStep(&TaskConfiguration::InstallationFSLocationStep);
+
+    AddStep(&TaskConfiguration::DetectUpdateInstallationStep);
+    AddStep(&TaskConfiguration::CheckRDSSupportStep);
+    AddStep(&TaskConfiguration::ConfigureWidgetLocationStep);
+    AddStep(&TaskConfiguration::PkgmgrStartStep);
+
+    AddStep(&TaskConfiguration::AppendTasklistStep);
+
+    AddStep(&TaskConfiguration::EndStep);
+}
+
+void TaskConfiguration::StartStep()
+{
+    _D("--------- <TaskConfiguration> : START ----------");
+}
+
+void TaskConfiguration::EndStep()
+{
+    m_context.job->UpdateProgress(InstallerContext::INSTALL_PARSE_CONFIG,
+            "Parse config.xml and set structure");
+    _D("--------- <TaskConfiguration> : END ----------");
+}
+
+void TaskConfiguration::PkgmgrStartStep()
+{
+    pkgMgrInterface()->sendProgress(0);
+}
+
+void TaskConfiguration::AppendTasklistStep()
+{
+    if (!m_context.isUpdateMode) {
+        _D("TaskConfiguration -> new installation task list");
+        m_context.job->appendNewInstallationTaskList();
+    } else {
+        _D("TaskConfiguration -> update installation task list");
+        m_context.job->appendUpdateInstallationTaskList();
+    }
+}
+
+std::shared_ptr<PackageManager::IPkgmgrSignal> TaskConfiguration::pkgMgrInterface()
+{
+    return m_context.job->GetInstallerStruct().pkgmgrInterface;
+}
+
+void TaskConfiguration::SetupTempDirStep()
+{
+    _D("widgetPath: %s", m_context.requestedPath.c_str());
+    _D("tempPath: %s", m_tempDir.c_str());
+    if (m_context.mode.extension == InstallMode::ExtensionType::DIR) {
+        if (m_context.mode.command ==
+                InstallMode::Command::REINSTALL) {
+            std::ostringstream tempPathBuilder;
+            tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+            tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
+            tempPathBuilder << "/";
+            tempPathBuilder << m_context.requestedPath;
+            m_tempDir = tempPathBuilder.str();
+        } else {
+            m_tempDir = m_context.requestedPath;
+        }
+    } else {
+        m_tempDir =
+            Jobs::WidgetInstall::createTempPath(
+                    m_context.mode.rootPath ==
+                        InstallMode::RootPath::RO);
+    }
+}
+
+void TaskConfiguration::UnzipConfigurationStep()
+{
+    _D("UnzipConfigurationStep");
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR) {
+        if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files
+        {
+            WidgetUnzip wgtUnzip(m_context.requestedPath);
+            wgtUnzip.unzipConfiguration(m_tempDir, &m_context.widgetConfig.packagingType);
+            m_configuration += m_tempDir + "/" + CONFIG_XML;
+        } else{
+            m_context.widgetConfig.packagingType = PKG_TYPE_HOSTED_WEB_APP;
+            m_configuration += m_context.requestedPath;
+        }
+    } else {
+        if (m_context.mode.command == InstallMode::Command::REINSTALL) {
+            std::string configFile = m_tempDir + "/" + CONFIG_XML;
+            if (!WrtUtilFileExists(configFile)) {
+                configFile = m_tempDir + "/" + WITH_OSP_XML;
+                if (!WrtUtilFileExists(configFile)) {
+                    std::string tzAppId = m_context.requestedPath.
+                        substr(m_context.requestedPath.find_last_of("/")+1);
+                    WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(
+                                DPL::FromUTF8String(tzAppId)));
+                    configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+                    configFile += "/";
+                    configFile += WITH_OSP_XML;
+                }
+            } else {
+                m_context.widgetConfig.packagingType = PKG_TYPE_NOMAL_WEB_APP;
+            }
+            m_configuration = configFile;
+        } else {
+            m_configuration = m_tempDir + "/" + WITH_OSP_XML;
+        }
+    }
+    _D("m_configuration : %s", m_configuration.c_str());
+    _D("Package Type : %s", m_context.widgetConfig.packagingType.getPkgtypeToString().c_str());
+}
+
+void TaskConfiguration::ParseXMLConfigStep()
+{
+    _D("ParseXMLConfigStep");
+    // Parse config
+    ParserRunner parser;
+    Try
+    {
+        if(!DPL::Utils::Path(m_configuration).Exists())
+        {
+            ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
+        }
+
+#ifdef SCHEMA_VALIDATION_ENABLED
+        if(!parser.Validate(configFilePath, WRT_WIDGETS_XML_SCHEMA))
+        {
+            _E("Invalid configuration file - schema validation failed");
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Failed to parse config.xml file");
+        }
+#endif
+        parser.Parse(m_configuration,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(m_widgetConfig,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        _E("Failed to parse config.xml file");
+        ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Parser exeption");
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+    {
+        _E("Failed to find installed widget - give proper tizenId");
+        ThrowMsg(Exceptions::RDSDeltaFailure, "WidgetNotExist");
+    }
+    Catch(Exceptions::WidgetConfigFileNotFound){
+        _E("Failed to find config.xml");
+        ThrowMsg(Exceptions::MissingConfig, "Parser exeption");
+    }
+
+    if (!WrtUtilRemove(m_configuration)) {
+        _E("Error occurs during removing %s", m_configuration.c_str());
+    }
+
+}
+
+void TaskConfiguration::TizenIdStep()
+{
+    bool shouldMakeAppid = false;
+    using namespace PackageManager;
+
+    if (!!m_widgetConfig.tizenAppId) {
+        _D("Setting tizenAppId provided in config.xml: %s", DPL::ToUTF8String(*m_widgetConfig.tizenAppId).c_str());
+
+        m_context.widgetConfig.tzAppid = *m_widgetConfig.tizenAppId;
+        //check package id.
+        if (!!m_widgetConfig.tizenPkgId) {
+            _D("Setting tizenPkgId provided in config.xml: %s", DPL::ToUTF8String(*m_widgetConfig.tizenPkgId).c_str());
+
+            m_context.widgetConfig.tzPkgid = *m_widgetConfig.tizenPkgId;
+        } else {
+            DPL::String appid = *m_widgetConfig.tizenAppId;
+            if (appid.length() > PACKAGE_ID_LENGTH) {
+                m_context.widgetConfig.tzPkgid =
+                    appid.substr(0, PACKAGE_ID_LENGTH);
+            } else {
+                //old version appid only has 10byte random character is able to install for a while.
+                //this case appid equal pkgid.
+                m_context.widgetConfig.tzPkgid =
+                    *m_widgetConfig.tizenAppId;
+                shouldMakeAppid = true;
+            }
+        }
+    } else {
+        shouldMakeAppid = true;
+        TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
+        _D("Checking if pkg id is unique");
+        while (true) {
+            if (!validateTizenPackageID(pkgId)) {
+                //path exist, chose another one
+                pkgId = WidgetDAOReadOnly::generatePkgId();
+                continue;
+            }
+            break;
+        }
+        m_context.widgetConfig.tzPkgid = pkgId;
+        _D("tizen_id name was generated by WRT: %ls", m_context.widgetConfig.tzPkgid.c_str());
+    }
+
+    if (shouldMakeAppid == true) {
+        DPL::OptionalString name;
+        DPL::OptionalString defaultLocale = m_widgetConfig.defaultlocale;
+
+        FOREACH(localizedData, m_widgetConfig.localizedDataSet)
+        {
+            Locale i = localizedData->first;
+            if (!!defaultLocale) {
+                if (defaultLocale == i) {
+                    name = localizedData->second.name;
+                    break;
+                }
+            } else {
+                name = localizedData->second.name;
+                break;
+            }
+        }
+        regex_t regx;
+        if (regcomp(&regx, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+            _D("Regcomp failed");
+        }
+
+        _D("Name : %ls", (*name).c_str());
+        if (!name || (regexec(&regx, DPL::ToUTF8String(*name).c_str(),
+                              static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
+        {
+            const std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+            std::ostringstream genName;
+            struct timeval tv;
+            gettimeofday(&tv, NULL);
+            unsigned int seed = time(NULL) + tv.tv_usec;
+
+            genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
+            name = DPL::FromUTF8String(genName.str());
+            _D("name was generated by WRT");
+        }
+        regfree(&regx);
+        _D("Name : %ls", (*name).c_str());
+        std::ostringstream genid;
+        genid << m_context.widgetConfig.tzPkgid << "." << name;
+        _D("tizen appid was generated by WRT : %s", genid.str().c_str());
+
+        DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
+        NormalizeAndTrimSpaceString(appid);
+        m_context.widgetConfig.tzAppid = *appid;
+    }
+
+    // send start signal of pkgmgr
+    pkgMgrInterface()->setPkgname(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid));
+
+    _D("Tizen App Id : %ls", (m_context.widgetConfig.tzAppid).c_str());
+    _D("Tizen Pkg Id : %ls", (m_context.widgetConfig.tzPkgid).c_str());
+}
+
+void TaskConfiguration::CheckAppRunningStateStep()
+{
+    bool isRunning = false;
+    int ret =
+        app_manager_is_running(DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str(),
+                               &isRunning);
+    if (APP_MANAGER_ERROR_NONE != ret) {
+        _E("Fail to get running state");
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                "widget is running");
+    }
+
+    if (true == isRunning) {
+        // get app_context for running application
+        // app_context must be released with app_context_destroy
+        app_context_h appCtx = NULL;
+        ret =
+            app_manager_get_app_context(
+                DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str(),
+                &appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to get app_context");
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                    "widget is running");
+        }
+
+        // terminate app_context_h
+        ret = app_manager_terminate_app(appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to terminate running application");
+            app_context_destroy(appCtx);
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                    "widget is running");
+        } else {
+            app_context_destroy(appCtx);
+            // app_manager_terminate_app isn't sync API
+            // wait until application isn't running (50ms * 100)
+            bool isStillRunning = true;
+            int checkingloop = 100;
+            struct timespec duration = { 0, 50 * 1000 * 1000 };
+            while (--checkingloop >= 0) {
+                nanosleep(&duration, NULL);
+                int ret = app_manager_is_running(
+                        DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str(),
+                        &isStillRunning);
+                if (APP_MANAGER_ERROR_NONE != ret) {
+                    _E("Fail to get running state");
+                    ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                            "widget is running");
+                }
+                if (!isStillRunning) {
+                    break;
+                }
+            }
+            if (isStillRunning) {
+                _E("Fail to terminate running application");
+                ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                        "widget is running");
+            }
+            _D("terminate application");
+        }
+    }
+}
+
+void TaskConfiguration::ConfigureWidgetLocationStep()
+{
+    m_context.locations =
+        WidgetLocation(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid),
+                       m_context.requestedPath, m_tempDir,
+                       m_context.widgetConfig.packagingType,
+                       m_context.mode.rootPath ==
+                           InstallMode::RootPath::RO,
+                           m_context.mode.extension);
+    m_context.locations->registerAppid(
+        DPL::ToUTF8String(m_context.widgetConfig.tzAppid));
+
+    _D("widgetSource %s", m_context.requestedPath.c_str());
+}
+
+void TaskConfiguration::DetectUpdateInstallationStep()
+{
+    WidgetUpdateInfo update;
+    // checking installed web application
+    Try {
+        // no excpetion means, it isn't update mode
+        update = detectWidgetUpdate(m_widgetConfig,
+                                    m_context.widgetConfig.tzAppid);
+        checkWidgetUpdate(update);
+
+        m_context.isUpdateMode = true;
+
+        //if update, notify pkgmgr that this is update
+        pkgMgrInterface()->startJob(InstallationType::UpdateInstallation);
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        pkgMgrInterface()->startJob(InstallationType::NewInstallation);
+
+        m_context.isUpdateMode = false;
+
+        if (!validateTizenApplicationID(
+            m_context.widgetConfig.tzAppid))
+        {
+            _E("tizen application ID is already used");
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
+                "invalid config");
+        }
+        if (!validateTizenPackageID(m_context.widgetConfig.tzPkgid)) {
+            _E("tizen package ID is already used");
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled,
+                "package is already installed");
+        }
+    }
+}
+
+void TaskConfiguration::CheckRDSSupportStep()
+{
+    //update needs RDS support to go ahead if REINSTALL command is given
+    if(m_context.isUpdateMode)
+    {
+        if (!checkSupportRDSUpdateIfReinstall(m_widgetConfig)) {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
+                "RDS update failed");
+        }
+    }
+}
+
+bool TaskConfiguration::validateTizenApplicationID(
+    const WrtDB::TizenAppId &tizenAppId)
+{
+    _D("tizen application ID = [%ls]", tizenAppId.c_str());
+
+    regex_t reg;
+    if (regcomp(&reg, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+        _D("Regcomp failed");
+        return false;
+    }
+
+    if (regexec(&reg, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
+        == REG_NOMATCH)
+    {
+        regfree(&reg);
+        return false;
+    }
+    regfree(&reg);
+    return true;
+}
+
+bool TaskConfiguration::validateTizenPackageID(
+    const WrtDB::TizenPkgId &tizenPkgId)
+{
+    _D("tizen application ID = [%ls]", tizenPkgId.c_str());
+
+    regex_t reg;
+    if (regcomp(&reg, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0)
+    {
+        _D("Regcomp failed");
+        return false;
+    }
+    if (regexec(&reg, DPL::ToUTF8String(tizenPkgId).c_str(), 0, NULL, 0) == REG_NOMATCH)
+    {
+        regfree(&reg);
+        return false;
+    }
+    regfree(&reg);
+    return true;
+}
+
+bool TaskConfiguration::checkWidgetUpdate(
+    const WidgetUpdateInfo &update)
+{
+    if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
+        return false;
+    }
+
+    _D("existing version = '%ls", update.existingVersion->Raw().c_str());
+    _D("incoming version = '%ls", update.incomingVersion->Raw().c_str());
+    _D("Tizen AppID = %ls", update.tzAppId.c_str());
+
+    m_context.widgetConfig.tzAppid = update.tzAppId;
+
+    if (!!update.existingVersion ||
+            m_context.mode.extension ==
+            InstallMode::ExtensionType::DIR) {
+        return true;
+    }
+
+    return false;
+}
+
+WidgetUpdateInfo TaskConfiguration::detectWidgetUpdate(
+    const ConfigParserData &configInfo,
+    const WrtDB::TizenAppId &tizenId)
+{
+    _D("Checking up widget package for config.xml...");
+    OptionalWidgetVersion incomingVersion;
+
+    if (!configInfo.version.IsNull()) {
+        incomingVersion =
+            DPL::Optional<WidgetVersion>(
+                WidgetVersion(*configInfo.version));
+    }
+
+    WidgetDAOReadOnly dao(tizenId);
+
+    OptionalWidgetVersion optVersion;
+    DPL::OptionalString version = dao.getVersion();
+    if (!version.IsNull()) {
+        optVersion = OptionalWidgetVersion(WidgetVersion(*version));
+    }
+
+    return WidgetUpdateInfo(
+        dao.getTzAppId(),
+        optVersion,
+        incomingVersion);
+}
+
+void TaskConfiguration::ApplicationTypeStep() //TODO: is this really needed as WAC is not supported?
+{
+    AppType widgetAppType = APP_TYPE_UNKNOWN;
+    FOREACH(iterator, m_widgetConfig.nameSpaces) {
+        _D("namespace = [%ls]", (*iterator).c_str());
+
+        if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            widgetAppType = APP_TYPE_TIZENWEBAPP;
+            break;
+        }
+    }
+
+    m_context.widgetConfig.webAppType = widgetAppType;
+
+    _D("type = [%s]", m_context.widgetConfig.webAppType.getApptypeToString().c_str());
+}
+
+void TaskConfiguration::ResourceEncryptionStep()
+{    
+    m_context.needEncryption = false;
+    FOREACH(it, m_widgetConfig.settingsList)
+    {
+        if (it->m_name == SETTING_VALUE_ENCRYPTION &&
+            it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
+        {
+            _D("resource need encryption");
+            m_context.needEncryption = true;
+        }
+    }
+}
+
+void TaskConfiguration::InstallationFSLocationStep()
+{
+    if (m_context.mode.installTime != InstallMode::InstallTime::PRELOAD) {
+        FOREACH(it, m_widgetConfig.settingsList) {
+            if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME) {
+                if (it->m_value == SETTING_VALUE_INSTALLTOEXT_AUTO) {
+                    m_context.locationType = INSTALL_LOCATION_TYPE_AUTO;
+                } else if (it->m_value == SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) {
+                    m_context.locationType =
+                        INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
+                } else {
+                    m_context.locationType =
+                        INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+                }
+                break;
+            }
+        }
+    }
+}
+
+bool TaskConfiguration::checkSupportRDSUpdateIfReinstall(const WrtDB::ConfigParserData
+        &configInfo)
+{
+    if (m_context.mode.command ==
+            InstallMode::Command::REINSTALL)
+    {
+        DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
+        DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
+
+        WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid);
+        WrtDB::WidgetSettings widgetSettings;
+        dao.getWidgetSettings(widgetSettings);
+
+        FOREACH(it, widgetSettings) {
+            if (it->settingName == SETTING_VALUE_ENCRYPTION) {
+                dbValue = it->settingValue;
+            }
+        }
+
+        FOREACH(data, configInfo.settingsList)
+        {
+            if (data->m_name == SETTING_VALUE_ENCRYPTION)
+            {
+                configValue = data->m_value;
+            }
+        }
+        if (configValue != dbValue) {
+            _E("Not Support RDS mode because of encryption setting");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+}
+}
diff --git a/src_mobile/jobs/widget_install/task_configuration.h b/src_mobile/jobs/widget_install/task_configuration.h
new file mode 100644 (file)
index 0000000..39e4701
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013 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_configuration.h
+ * @version 1.0
+ * @author  Tomasz Iwanek
+ * @brief   header file for configuration task
+ */
+#ifndef TASK_CONFIGURATION_H
+#define TASK_CONFIGURATION_H
+
+#include <string>
+
+#include <dpl/task_list.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+
+#include <widget_install/widget_update_info.h>
+#include <widget_install/widget_install_context.h>
+
+#include <pkg-manager/pkgmgr_signal.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+class TaskConfiguration : public DPL::TaskDecl<TaskConfiguration>
+{
+    InstallerContext& m_context;
+    std::string m_tempDir;
+    WrtDB::ConfigParserData &m_widgetConfig;
+    std::string m_configuration;
+
+    WidgetUpdateInfo m_widgetUpdateInfo;
+
+    void parseWidgetXMLConfig(
+        const std::string &widgetSource,
+        const std::string &tempPath,
+        WrtDB::PackagingType pkgType,
+        bool isReinstall);
+
+    static WidgetUpdateInfo detectWidgetUpdate(
+        const WrtDB::ConfigParserData &configInfo,
+        const WrtDB::TizenAppId &tizenId);
+
+    bool validateTizenApplicationID(const WrtDB::TizenAppId &tizenAppId);
+    bool validateTizenPackageID(const WrtDB::TizenPkgId &tizenPkgId);
+    bool checkWidgetUpdate(const WidgetUpdateInfo &update);
+    void ApplicationTypeStep(const WrtDB::ConfigParserData &configInfo);
+    bool checkSupportRDSUpdateIfReinstall(const WrtDB::ConfigParserData &configInfo);
+    bool getDefaultExternalStorage();
+    bool getMMCStatus();
+
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgMgrInterface();
+
+    //steps
+    void StartStep();
+
+    void SetupTempDirStep();
+    void UnzipConfigurationStep();
+    void ParseXMLConfigStep();
+
+    void TizenIdStep();
+    void CheckAppRunningStateStep();
+    void DetectUpdateInstallationStep();
+    void PkgmgrStartStep();
+
+    void ApplicationTypeStep();
+    void ResourceEncryptionStep();
+    void InstallationFSLocationStep();
+
+    void ConfigureWidgetLocationStep();
+    void CheckRDSSupportStep();
+
+    void AppendTasklistStep();
+    void EndStep();
+
+public:
+    TaskConfiguration(InstallerContext& context);
+};
+
+}
+}
+
+#endif // TASK_CONFIGURATION_H
diff --git a/src_mobile/jobs/widget_install/task_database.cpp b/src_mobile/jobs/widget_install/task_database.cpp
new file mode 100644 (file)
index 0000000..9dc4e15
--- /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    task_new_db_insert.cpp
+ * @author  Lukasz Wrzosek(l.wrzosek@samsung.com)
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task database updating for widget
+ * update
+ */
+#include <unistd.h>
+#include <cstdio>
+#include <time.h>
+#include <sys/stat.h>
+#include <widget_install/task_database.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <web_provider_livebox_info.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/assert.h>
+#include <wrt-commons/security-origin-dao/security_origin_dao.h>
+#include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_types.h>
+#include <string>
+#include <sstream>
+#include <ace_api_install.h>
+#include <ace_registration.h>
+#include <errno.h>
+#include <string.h>
+#include <map>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskDatabase::TaskDatabase(InstallerContext& context) :
+    DPL::TaskDecl<TaskDatabase>(this),
+    m_context(context),
+    m_handleToRemove(INVALID_WIDGET_HANDLE),
+    m_handle(INVALID_WIDGET_HANDLE)
+{
+    AddStep(&TaskDatabase::StartStep);
+    AddStep(&TaskDatabase::StepRegisterExternalFiles);
+    AddStep(&TaskDatabase::StepWrtDBInsert);
+    AddStep(&TaskDatabase::StepAceDBInsert);
+    AddStep(&TaskDatabase::StepSecurityOriginDBInsert);
+    AddStep(&TaskDatabase::StepWidgetInterfaceDBInsert);
+    AddStep(&TaskDatabase::StepRemoveExternalFiles);
+    AddStep(&TaskDatabase::StepLiveboxDBInsert);
+    AddStep(&TaskDatabase::EndStep);
+
+    AddAbortStep(&TaskDatabase::StepAbortDBInsert);
+    AddAbortStep(&TaskDatabase::StepAbortAceDBInsert);
+    AddAbortStep(&TaskDatabase::StepAbortWidgetInterfaceDBInsert);
+}
+
+void TaskDatabase::StepWrtDBInsert()
+{
+    Try
+    {
+        /* Set install Time */
+        time(&m_context.widgetConfig.installedTime);
+
+        if (m_context.isUpdateMode) { //update
+            _D("Registering widget... (update)");
+            Try
+            {
+                m_handleToRemove = WidgetDAOReadOnly::getHandle(
+                        m_context.widgetConfig.tzAppid);
+
+                std::string makeAppid =
+                    DPL::ToUTF8String(m_context.widgetConfig.tzAppid) + "." +
+                    "backup";
+                m_backAppId = DPL::FromUTF8String(makeAppid);
+            }
+            Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+            {
+                _E("Given tizenId not found for update installation (Same GUID?)");
+                ThrowMsg(Exceptions::DatabaseFailure,
+                         "Given tizenId not found for update installation");
+            }
+
+            WidgetDAO::updateTizenAppId(m_context.widgetConfig.tzAppid,
+                                        m_backAppId);
+            WidgetDAO::registerWidget(m_context.widgetConfig.tzAppid,
+                                      m_context.widgetConfig,
+                                      m_context.widgetSecurity);
+            m_handle =
+                WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+        } else { //new installation
+            _D("Registering widget...");
+            WidgetDAO::registerWidget(
+                m_context.widgetConfig.tzAppid,
+                m_context.widgetConfig,
+                m_context.widgetSecurity);
+            m_handle = WidgetDAOReadOnly::getHandle(
+                    m_context.widgetConfig.tzAppid);
+        }
+
+        FOREACH(cap, m_context.staticPermittedDevCaps) {
+            _D("staticPermittedDevCaps : %ls smack status: %d", cap->first.c_str(), cap->second);
+        }
+
+        _D("Widget registered");
+    }
+    Catch(WidgetDAO::Exception::DatabaseError)
+    {
+        _E("Database failure!");
+        ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!");
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base)
+    {
+        _E("Database failure!");
+        ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!");
+    }
+}
+
+void TaskDatabase::StepAceDBInsert()
+{
+    _D("Inserting Ace database entry. New handle: %d", m_handle);
+    if (INVALID_WIDGET_HANDLE != m_handleToRemove) {
+        _D("Removing old insallation. Handle: %d", m_handleToRemove);
+        if (ACE_OK != ace_unregister_widget(
+                static_cast<ace_widget_handle_t>(m_handleToRemove)))
+        {
+            _W("Error while removing ace entry for previous insallation");
+        }
+    }
+
+    if (!AceApi::registerAceWidget(m_handle, m_context.widgetConfig,
+                                   m_context.widgetSecurity.getCertificateList()))
+    {
+        _E("ace database insert failed");
+        ThrowMsg(Exceptions::UpdateFailed,
+                 "Update failure. ace_register_widget failed");
+    }
+    _D("Ace data inserted");
+}
+
+void TaskDatabase::StepSecurityOriginDBInsert()
+{
+    _D("Create Security origin database");
+    // automatically create security origin database
+    using namespace SecurityOriginDB;
+    using namespace WrtDB;
+
+    SecurityOriginDAO dao(m_context.locations->getPkgId());
+
+    // Checking privilege list for setting security origin exception data
+    FOREACH(it, m_context.widgetConfig.configInfo.privilegeList) {
+        std::map<std::string, Feature>::const_iterator result =
+            g_W3CPrivilegeTextMap.find(DPL::ToUTF8String(it->name));
+        if (result != g_W3CPrivilegeTextMap.end()) {
+            if (result->second == FEATURE_USER_MEDIA) {
+                dao.setPrivilegeSecurityOriginData(result->second, false);
+            } else if (result->second == FEATURE_FULLSCREEN_MODE) {
+                continue;
+            } else {
+                dao.setPrivilegeSecurityOriginData(result->second);
+            }
+        }
+    }
+}
+
+void TaskDatabase::StepWidgetInterfaceDBInsert()
+{
+    _D("Create Widget Interface database");
+    using namespace WidgetInterfaceDB;
+    using namespace WrtDB;
+
+    DbWidgetHandle handle =
+        WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+
+    // backup database
+    if (m_context.isUpdateMode) {
+        std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
+        std::string backupDbPath = dbPath;
+        backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
+        _D("\"%s\" to \"%s\"", dbPath.c_str(), backupDbPath.c_str());
+        if (0 != std::rename(dbPath.c_str(), backupDbPath.c_str())) {
+            _E("widget interface database backup failed");
+            ThrowMsg(Exceptions::UpdateFailed,
+                     "widget interface database backup failed");
+        }
+    }
+
+    Try
+    {
+        // automatically create widget interface database
+        WidgetInterfaceDAO dao(handle);
+    }
+    Catch(WidgetInterfaceDAO::Exception::DatabaseError)
+    {
+        _E("widget interface database create failed");
+        ThrowMsg(Exceptions::UpdateFailed,
+                 "widget interface database create failed");
+    }
+}
+
+void TaskDatabase::StepRegisterExternalFiles()
+{
+    WrtDB::ExternalLocationList externalLocationsUpdate =
+        m_context.locations->listExternalLocations();
+    if (m_context.isUpdateMode) { //update
+        Try
+        {
+            WidgetDAO dao(m_context.widgetConfig.tzAppid);
+            WrtDB::ExternalLocationList externalLocationsDB =
+                dao.getWidgetExternalLocations();
+            FOREACH(file, externalLocationsDB)
+            {
+                if (std::find(externalLocationsUpdate.begin(),
+                              externalLocationsUpdate.end(),
+                              *file) == externalLocationsUpdate.end())
+                {
+                    m_externalLocationsToRemove.push_back(*file);
+                }
+            }
+        }
+        Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+        {
+            _E("Given tizenId not found for update installation (Same GUID?)");
+            ThrowMsg(Exceptions::UpdateFailed,
+                     "Given tizenId not found for update installation");
+        }
+    }
+    _D("Registering external files:");
+    FOREACH(file, externalLocationsUpdate)
+    {
+        _D("  -> %s", (*file).c_str());
+    }
+
+    //set external locations to be registered
+    m_context.widgetConfig.externalLocations = externalLocationsUpdate;
+}
+
+void TaskDatabase::StepRemoveExternalFiles()
+{
+    if (!m_externalLocationsToRemove.empty()) {
+        _D("Removing external files:");
+    }
+
+    FOREACH(file, m_externalLocationsToRemove)
+    {
+        if (WrtUtilFileExists(*file)) {
+            _D("  -> %s", (*file).c_str());
+            if (-1 == TEMP_FAILURE_RETRY(remove(file->c_str()))) {
+                ThrowMsg(Exceptions::RemovingFileFailure,
+                         "Failed to remove external file");
+            }
+        } else if (WrtUtilDirExists(*file)) {
+            _D("  -> %s", (*file).c_str());
+            if (!WrtUtilRemove(*file)) {
+                ThrowMsg(Exceptions::RemovingFolderFailure,
+                         "Failed to remove external directory");
+            }
+        } else {
+            _W("  -> %s(no such a path)", (*file).c_str());
+        }
+    }
+}
+
+void TaskDatabase::StepAbortDBInsert()
+{
+    _W("[DB Update Task] Aborting... (DB Clean)");
+    Try
+    {
+        if (m_context.isUpdateMode) {
+            WidgetDAO::unregisterWidget(m_context.widgetConfig.tzAppid);
+            WidgetDAO::updateTizenAppId(m_backAppId,
+                                        m_context.widgetConfig.tzAppid);
+        } else {
+            WidgetDAO::unregisterWidget(m_context.widgetConfig.tzAppid);
+        }
+        _D("Cleaning DB successful!");
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base)
+    {
+        _E("Failed to handle StepAbortDBClean!");
+    }
+}
+
+void TaskDatabase::StepAbortAceDBInsert()
+{
+    _W("[DB Update Task] ACE DB Aborting... (DB Clean)");
+
+    ace_unregister_widget(static_cast<ace_widget_handle_t>(m_handle));
+    // Remove also old one. If it was already updated nothing wrong will happen,
+    // but if not old widget will be removed.
+    if (INVALID_WIDGET_HANDLE != m_handleToRemove) {
+        ace_unregister_widget(static_cast<ace_widget_handle_t>(m_handle));
+    }
+
+    if (!AceApi::registerAceWidgetFromDB(m_handleToRemove))
+    {
+        _E("ace database restore failed");
+    }
+    _D("Ace data inserted");
+}
+
+void TaskDatabase::StepAbortWidgetInterfaceDBInsert()
+{
+    _D("[DB Update Task] Widget interface Aborting...");
+    using namespace WidgetInterfaceDB;
+    using namespace WrtDB;
+
+    DbWidgetHandle handle =
+        WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+    std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
+
+    // remove database
+    if (remove(dbPath.c_str()) != 0) {
+        _W("Fail to remove");
+    }
+
+    // rollback database
+    if (m_context.isUpdateMode) {
+        std::string backupDbPath = dbPath;
+        backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
+        _D("\"%s\" to \"%s\"", dbPath.c_str(), backupDbPath.c_str());
+        if (0 != std::rename(backupDbPath.c_str(), dbPath.c_str())) {
+            _W("Fail to rollback");
+        }
+    }
+}
+
+void TaskDatabase::StepLiveboxDBInsert()
+{
+    if (m_context.widgetConfig.configInfo.m_livebox.size() <= 0) {
+        return;
+    }
+
+    std::string tizenId = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+
+    // insert specific information to web livebox db
+    for (auto it = m_context.widgetConfig.configInfo.m_livebox.begin();
+         it != m_context.widgetConfig.configInfo.m_livebox.end(); ++it)
+    {
+        std::string boxId = DPL::ToUTF8String((**it).m_liveboxId);
+        std::string boxType;
+        if ((**it).m_type.empty()) {
+            boxType = web_provider_livebox_get_default_type();
+        } else {
+            boxType = DPL::ToUTF8String((**it).m_type);
+        }
+        _D("livebox id: %s", boxId.c_str());
+        _D("livebox type: %s", boxType.c_str());
+
+        int autoLaunch = (**it).m_autoLaunch == L"true" ? 1 : 0;
+        _D("livebox auto-launch: %d", autoLaunch);
+
+        int mouseEvent = (**it).m_boxInfo.m_boxMouseEvent == L"true" ? 1 : 0;
+        _D("livebox mouse-event: %d", mouseEvent);
+
+        int pdFastOpen = (**it).m_boxInfo.m_pdFastOpen == L"true" ? 1 : 0;
+        _D("livebox pd fast-open: %d", pdFastOpen);
+
+        web_provider_livebox_insert_box_info(
+                boxId.c_str(), tizenId.c_str(), boxType.c_str(),
+                autoLaunch, mouseEvent, pdFastOpen);
+    }
+}
+
+void TaskDatabase::StartStep()
+{
+    _D("--------- <TaskDatabase> : START ----------");
+}
+
+void TaskDatabase::EndStep()
+{
+    _D("--------- <TaskDatabase> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_database.h b/src_mobile/jobs/widget_install/task_database.h
new file mode 100644 (file)
index 0000000..1291c36
--- /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    task_database.h
+ * @author  Lukasz Wrzosek(l.wrzosek@samsung.com)
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task database updating
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H
+
+#include <dpl/task.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskDatabase :
+    public DPL::TaskDecl<TaskDatabase>
+{
+  private:
+    InstallerContext& m_context;
+    WrtDB::ExternalLocationList m_externalLocationsToRemove;
+
+    //TODO: temporary needed until security-server start to use pkgName instead
+    //of widget handle
+    WrtDB::DbWidgetHandle m_handleToRemove;
+    WrtDB::DbWidgetHandle m_handle;
+    WrtDB::TizenAppId m_backAppId;
+
+    void StepRegisterExternalFiles();
+    void StepWrtDBInsert();
+    void StepAceDBInsert();
+    void StepSecurityOriginDBInsert();
+    void StepWidgetInterfaceDBInsert();
+    void StepRemoveExternalFiles();
+    void StepLiveboxDBInsert();
+
+    void StepAbortDBInsert();
+    void StepAbortAceDBInsert();
+    void StepAbortWidgetInterfaceDBInsert();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskDatabase(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H
diff --git a/src_mobile/jobs/widget_install/task_encrypt_resource.cpp b/src_mobile/jobs/widget_install/task_encrypt_resource.cpp
new file mode 100644 (file)
index 0000000..3966ca8
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * 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_ecnrypt_resource.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task encrypt resource
+ */
+#include "task_encrypt_resource.h"
+
+#undef __USE_FILE_OFFSET64
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fts.h>
+#include <string.h>
+#include <errno.h>
+#include <cstdio>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+#include <memory>
+
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_fclose.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/string.h>
+#include <ss_manager.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const std::size_t ENCRYPTION_CHUNK_MAX_SIZE = 8192; // bytes
+const std::size_t ENCRYPTION_DEC_CHUNK_SIZE = 4; // bytes
+
+std::set<std::string>& getSupportedForEncryption()
+{
+    static std::set<std::string> encryptSet;
+    if (encryptSet.empty()) {
+        encryptSet.insert(".html");
+        encryptSet.insert(".htm");
+        encryptSet.insert(".css");
+        encryptSet.insert(".js");
+    }
+    return encryptSet;
+}
+
+bool isSupportedForEncryption(const std::string &file)
+{
+    size_t foundKey = file.rfind(".");
+    if (std::string::npos != foundKey) {
+        std::string mimeType = file.substr(foundKey);
+        std::transform(mimeType.begin(), mimeType.end(), mimeType.begin(),
+                       ::tolower);
+
+        return getSupportedForEncryption().count(mimeType) > 0;
+    }
+    return false;
+}
+
+/**
+ * Opens a file.
+ *
+ * @param path Path to a file.
+ * @param mode Mode.
+ * @return Stream handle.
+ * @throw ExtractFileFailed If error (other than EINTR) occurs.
+ */
+FILE* openFile(const std::string& path, const std::string& mode)
+{
+    FILE* result = NULL;
+
+    do
+    {
+        result = fopen(path.c_str(), mode.c_str());
+    } while ((NULL == result) && (EINTR == errno));
+
+    if (NULL == result)
+    {
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::EncryptionFailed,
+                 "Could not open file " << path);
+    }
+
+    return result;
+}
+
+/**
+ * Reads bytes from a stream.
+ *
+ * @param buffer Buffer to read the bytes into.
+ * @param count Number of bytes to read.
+ * @param stream Stream to read from.
+ * @return Number of bytes read
+ * @throw ExtractFileFailed If error (other than EINTR) occurs.
+ */
+std::size_t readBytes(unsigned char* buffer, std::size_t count, FILE* stream)
+{
+    std::size_t result = std::fread(buffer,
+                                    sizeof(unsigned char),
+                                    count,
+                                    stream);
+
+    if (result != count)
+    {
+        int error = errno;
+        if (0 != std::ferror(stream))
+        {
+            if (EINTR != error)
+            {
+                ThrowMsg(Jobs::WidgetInstall::Exceptions::ErrorExternalInstallingFailure,
+                         "Error while reading data" <<
+                         " [" << DPL::GetErrnoString(error) << "]");
+            }
+        }
+    }
+
+    return result;
+}
+
+/**
+ * Writes bytes to a stream.
+ *
+ * @param buffer Data to write.
+ * @param count Number of bytes.
+ * @param stream Stream to write to.
+ * @throw ExtractFileFailed If error (other than EINTR) occurs.
+ */
+void writeBytes(unsigned char* buffer, std::size_t count, FILE* stream)
+{
+    std::size_t bytesWritten = 0;
+    std::size_t bytesToWrite = 0;
+    do
+    {
+        bytesToWrite = count - bytesWritten;
+        bytesWritten = std::fwrite(buffer + bytesWritten,
+                                   sizeof(unsigned char),
+                                   count - bytesWritten,
+                                   stream);
+        if ((bytesWritten != bytesToWrite) && (EINTR != errno))
+        {
+            int error = errno;
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::EncryptionFailed,
+                     "Error while writing data" <<
+                     " [" << DPL::GetErrnoString(error) << "]");
+        }
+    } while ((bytesWritten != bytesToWrite) && (EINTR == errno));
+}
+
+int ssmEncrypt(InstallMode::InstallTime time, std::string pkgId, const char*
+        inChunk, int inBytes, char** outChunk, int *outBytes)
+{
+    if (time == InstallMode::InstallTime::PRELOAD) {
+        return ssm_encrypt_preloaded_application(inChunk, inBytes,
+                outChunk, outBytes);
+    } else {
+        return ssm_encrypt(pkgId.c_str(), pkgId.length(),
+                inChunk, inBytes,
+                outChunk, outBytes);
+    }
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskEncryptResource::TaskEncryptResource(InstallerContext& context) :
+    DPL::TaskDecl<TaskEncryptResource>(this),
+    m_context(context)
+{
+    AddStep(&TaskEncryptResource::StartStep);
+    AddStep(&TaskEncryptResource::StepEncryptResource);
+    AddStep(&TaskEncryptResource::EndStep);
+}
+
+void TaskEncryptResource::StepEncryptResource()
+{
+    _D("Step Encrypt resource");
+
+    EncryptDirectory(m_context.locations->getSourceDir());
+}
+
+void TaskEncryptResource::EncryptDirectory(std::string path)
+{
+    FTS *fts;
+    FTSENT *ftsent;
+    char * const paths[] = { const_cast<char * const>(path.c_str()), NULL };
+
+    if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) {
+        //ERROR
+        int error = errno;
+        _W("%s: fts_open failed with error: %s", __PRETTY_FUNCTION__, strerror(error));
+        ThrowMsg(Exceptions::EncryptionFailed, "Error reading directory: "
+                 << path);
+    }
+
+    while ((ftsent = fts_read(fts)) != NULL) {
+        switch (ftsent->fts_info) {
+        case FTS_DP:
+        case FTS_DC:
+        case FTS_D:
+        case FTS_DEFAULT:
+        case FTS_SLNONE:
+            //directories, non-regular files, dangling symbolic links
+            break;
+        case FTS_F:
+        case FTS_NSOK:
+        case FTS_SL:
+            //regular files and other objects that can be counted
+            if (isSupportedForEncryption(ftsent->fts_path)) {
+                EncryptFile(ftsent->fts_path);
+            }
+            break;
+        case FTS_NS:
+        case FTS_DOT:
+        case FTS_DNR:
+        case FTS_ERR:
+        default:
+            _W("%s: traversal failed on file: %s with error: %s", __PRETTY_FUNCTION__, ftsent->fts_path, strerror(ftsent->fts_errno));
+            ThrowMsg(Exceptions::EncryptionFailed, "Error reading file");
+            break;
+        }
+    }
+
+    if (fts_close(fts) == -1) {
+        int error = errno;
+        _W("%s: fts_close failed with error: %s", __PRETTY_FUNCTION__, strerror(error));
+    }
+}
+
+void TaskEncryptResource::EncryptFile(const std::string &fileName)
+{
+    _D("Encrypt file: %s", fileName.c_str());
+    std::string encFile = fileName + ".enc";
+
+    struct stat info;
+    memset(&info, 0, sizeof(info));
+    if (stat(fileName.c_str(), &info) != 0)
+    {
+        int error = errno;
+        ThrowMsg(Exceptions::EncryptionFailed,
+                "Could not access file " << fileName <<
+                "[" << DPL::GetErrnoString(error) << "]");
+    }
+    const std::size_t fileSize = info.st_size;
+    if (0 == fileSize) {
+        _D("%s size is 0, so encryption is skiped", fileName.c_str());
+        return;
+    }
+
+    // If update installed preload web, should skip encryption.
+    if (!(m_context.mode.rootPath == InstallMode::RootPath::RO &&
+                m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+
+        DPL::ScopedFClose inFile(openFile(fileName, "r"));
+        DPL::ScopedFClose outFile(openFile(encFile, "w"));
+
+        const std::size_t chunkSize = (fileSize > ENCRYPTION_CHUNK_MAX_SIZE
+                ? ENCRYPTION_CHUNK_MAX_SIZE : fileSize);
+
+        std::unique_ptr<unsigned char[]> inChunk(new unsigned char[chunkSize]);
+        std::size_t bytesRead = 0;
+        /* TODO : pkgId should change to appId after wrt-client label changed. */
+        std::string pkgId = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+
+        do
+        {
+            bytesRead = readBytes(inChunk.get(), chunkSize, inFile.Get());
+            if (0 != bytesRead) {
+                int outDecSize = 0;
+                char *outChunk = NULL;
+                if (0 != ssmEncrypt(m_context.mode.installTime, pkgId,
+                            (char*)inChunk.get(), (int)bytesRead,
+                            &outChunk, &outDecSize)) {
+                    ThrowMsg(Exceptions::EncryptionFailed,
+                            "Encryption Failed using TrustZone");
+                }
+
+                std::stringstream toString;
+                toString << outDecSize;
+
+                writeBytes((unsigned char*)toString.str().c_str(),
+                        sizeof(int), outFile.Get());
+                writeBytes((unsigned char*)outChunk, outDecSize, outFile.Get());
+                delete outChunk;
+            }
+            inChunk.reset(new unsigned char[chunkSize]);
+
+        } while (0 == std::feof(inFile.Get()));
+
+        outFile.Reset();
+        inFile.Reset();
+
+        _D("File encrypted successfully");
+        _D("Remove plain-text file: %s", fileName.c_str());
+        if (0 != unlink(fileName.c_str()))
+        {
+            Throw(Exceptions::EncryptionFailed);
+        }
+
+        _D("Rename encrypted file");
+        if (0 != std::rename(encFile.c_str(), fileName.c_str()))
+        {
+            Throw(Exceptions::EncryptionFailed);
+        }
+    }
+
+    WrtDB::EncryptedFileInfo fileInfo;
+    fileInfo.fileName = DPL::FromUTF8String(fileName);
+    fileInfo.fileSize = fileSize;
+
+    m_context.widgetConfig.encryptedFiles.insert(fileInfo);
+}
+
+void TaskEncryptResource::StartStep()
+{
+    _D("--------- <TaskEncryptResource> : START ----------");
+}
+
+void TaskEncryptResource::EndStep()
+{
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_ECRYPTION_FILES,
+            "Ecrypt resource files");
+
+    _D("--------- <TaskEncryptResource> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_encrypt_resource.h b/src_mobile/jobs/widget_install/task_encrypt_resource.h
new file mode 100644 (file)
index 0000000..b89a992
--- /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_encrypt_resource.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_RESOURCE_ENCRYPT_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_RESOURCE_ENCRYPT_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskEncryptResource : public DPL::TaskDecl<TaskEncryptResource>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+    std::string tempInstalledPath;
+
+    void StepEncryptResource();
+
+    void StartStep();
+    void EndStep();
+
+    void EncryptDirectory(std::string path);
+    void EncryptFile(const std::string &fileName);
+
+  public:
+    explicit TaskEncryptResource(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_ENCRYPT_RESOURCE_H_ */
diff --git a/src_mobile/jobs/widget_install/task_file_manipulation.cpp b/src_mobile/jobs/widget_install/task_file_manipulation.cpp
new file mode 100644 (file)
index 0000000..5e08d28
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2010 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 <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <string>
+#include <fstream>
+#include <vconf.h>
+
+#include <widget_install/task_file_manipulation.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/directory_api.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/foreach.h>
+#include <dpl/assert.h>
+#include <dpl/errno_string.h>
+#include <dpl/utils/folder_size.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <widget_install_to_external.h>
+#include <installer_log.h>
+#include <widget_unzip.h>
+
+#define WEBAPP_DEFAULT_UID  5000
+#define WEBAPP_DEFAULT_GID  5000
+
+namespace {
+const mode_t PRIVATE_STORAGE_MODE = 0700;
+const mode_t SHARED_STORAGE_MODE = 0755;
+}
+
+using namespace WrtDB;
+
+namespace {
+const char* GLIST_RES_DIR = "res";
+
+bool _FolderCopy(std::string source, std::string dest)
+{
+    DIR* dir = opendir(source.c_str());
+    if (NULL == dir) {
+        return false;
+    }
+
+    struct dirent dEntry;
+    struct dirent *dEntryResult;
+    int return_code;
+
+    do {
+        struct stat statInfo;
+        return_code = readdir_r(dir, &dEntry, &dEntryResult);
+        if (dEntryResult != NULL && return_code == 0) {
+            std::string fileName = dEntry.d_name;
+            std::string fullName = source + "/" + fileName;
+
+            if (stat(fullName.c_str(), &statInfo) != 0) {
+                closedir(dir);
+                return false;
+            }
+
+            if (S_ISDIR(statInfo.st_mode)) {
+                if (("." == fileName) || (".." == fileName)) {
+                    continue;
+                }
+                std::string destFolder = dest + "/" + fileName;
+                WrtUtilMakeDir(destFolder);
+
+                if (!_FolderCopy(fullName, destFolder)) {
+                    closedir(dir);
+                    return false;
+                }
+            }
+
+            std::string destFile = dest + "/" + fileName;
+            std::ifstream infile(fullName);
+            std::ofstream outfile(destFile);
+            outfile << infile.rdbuf();
+            outfile.close();
+            infile.close();
+        }
+    } while (dEntryResult != NULL && return_code == 0);
+    closedir(dir);
+    return true;
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
+    DPL::TaskDecl<TaskFileManipulation>(this),
+    m_context(context),
+    m_extHandle(NULL)
+{
+    AddStep(&TaskFileManipulation::StartStep);
+    AddStep(&TaskFileManipulation::StepCheckInstallLocation);
+    AddStep(&TaskFileManipulation::StepPrepareRootDirectory);
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
+    {
+        AddStep(&TaskFileManipulation::StepUnzipWgtFile);
+    }
+    AddStep(&TaskFileManipulation::EndStep);
+
+    AddAbortStep(&TaskFileManipulation::StepAbortPrepareRootDirectory);
+}
+
+void TaskFileManipulation::StepCheckInstallLocation()
+{
+    _D("StepCheckInstallLocation");
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+        return;
+    }
+
+    std::string installedPath = WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    WidgetUnzip wgtUnzip(m_context.requestedPath);
+
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_AUTO) {
+        int storage = 0;
+        // vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT)
+        // 0 : phone internal memory
+        // 1 : SD card
+        if (vconf_get_int("db/setting/default_memory/download_application",
+                    &storage)) {
+            _E("vconf_get_int(db/setting/default_memory/download_application) \
+                    failed.");
+        }
+        _D("default setting : storage [%d]", storage);
+        if (storage) {
+            m_context.locationType = INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
+        } else {
+            m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+            if(!wgtUnzip.checkAvailableSpace(installedPath)) {
+                m_context.locationType = INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
+            }
+        }
+    }
+
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
+        int mmcStatus;
+        if (vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmcStatus)) {
+            _E("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
+            mmcStatus = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
+        }
+
+        if (VCONFKEY_SYSMAN_MMC_MOUNTED != mmcStatus) {
+            _D("mmcStatus is MMC_REMOVED or NOT_MOUNTED.");
+            m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+        }
+    }
+
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_INTERNAL_ONLY) {
+        if(!wgtUnzip.checkAvailableSpace(installedPath)) {
+            ThrowMsg(Exceptions::OutOfStorageFailed, "There is no space for installation");
+        }
+    }
+}
+
+void TaskFileManipulation::StepPrepareRootDirectory()
+{
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
+        prepareExternalDir();
+    } else {
+        std::string widgetPath = m_context.locations->getPackageInstallationDir();
+        std::string widgetBinPath = m_context.locations->getBinaryDir();
+        std::string widgetSrcPath = m_context.locations->getSourceDir();
+
+        WrtUtilMakeDir(widgetPath);
+
+        _D("Create resource directory");
+        WrtUtilMakeDir(widgetBinPath);
+        WrtUtilMakeDir(widgetSrcPath);
+        if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
+            std::string userWidgetDir = m_context.locations->getUserDataRootDir();
+            WrtUtilMakeDir(userWidgetDir);
+        }
+    }
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_DIR_CREATE,
+        "Widget Directory Created");
+}
+
+void TaskFileManipulation::StepUnzipWgtFile()
+{
+    if (m_context.widgetConfig.packagingType != PKG_TYPE_HOSTED_WEB_APP) {
+        std::string instDir;
+        if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
+            instDir = m_context.locations->getPackageInstallationDir();
+        } else {
+            instDir = m_context.locations->getSourceDir();
+        }
+
+        _D("unzip file to %s", instDir.c_str());
+
+        WidgetUnzip wgtUnzip(m_context.requestedPath);
+        wgtUnzip.unzipWgtFile(instDir);
+    } else {
+        _D("From browser installation - unzip is not done");
+    }
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_UNZIP_WGT,
+        "Unzip Wgt file");
+}
+
+void TaskFileManipulation::StepAbortPrepareRootDirectory()
+{
+    _D("[Create Root Directory]  Aborting.... (Rename path)");
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
+        if (m_context.isUpdateMode) {
+            WidgetInstallToExtSingleton::Instance().postUpgrade(false);
+        } else {
+            WidgetInstallToExtSingleton::Instance().postInstallation(false);
+        }
+        WidgetInstallToExtSingleton::Instance().deinitialize();
+    } else {
+        std::string widgetPath;
+        widgetPath = m_context.locations->getPackageInstallationDir();
+        if (!WrtUtilRemove(widgetPath)) {
+            _E("Error occurs during removing existing folder");
+        }
+        // Remove user data directory if preload web app.
+        std::string userData = m_context.locations->getUserDataRootDir();
+        if (0 == access(userData.c_str(), F_OK)) {
+            if (!WrtUtilRemove(userData)) {
+                _E("Error occurs during removing user data directory");
+            }
+        }
+    }
+}
+
+void TaskFileManipulation::prepareExternalDir()
+{
+    _D("Step prepare to install in exernal directory");
+    Try {
+        std::string pkgid =
+            DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+
+        WidgetInstallToExtSingleton::Instance().initialize(pkgid);
+
+        std::unique_ptr<DPL::ZipInput> zipFile(new
+                DPL::ZipInput(m_context.requestedPath));
+        double unzipSize = zipFile->GetTotalUncompressedSize();
+        int folderSize = (int)(unzipSize / (1024 * 1024)) + 1;
+
+        GList *list = NULL;
+        app2ext_dir_details* dirDetail = NULL;
+
+        dirDetail = (app2ext_dir_details*) calloc(1,
+                sizeof(
+                    app2ext_dir_details));
+        if (NULL == dirDetail) {
+            ThrowMsg(Exceptions::ErrorExternalInstallingFailure,
+                    "error in app2ext");
+        }
+        dirDetail->name = strdup(GLIST_RES_DIR);
+        dirDetail->type = APP2EXT_DIR_RO;
+        list = g_list_append(list, dirDetail);
+
+        if (m_context.isUpdateMode) {
+            WidgetInstallToExtSingleton::Instance().preUpgrade(list,
+                                                               folderSize);
+        } else {
+            WidgetInstallToExtSingleton::Instance().preInstallation(list,
+                                                                    folderSize);
+        }
+        free(dirDetail);
+        g_list_free(list);
+
+        /* make bin directory */
+        std::string widgetBinPath = m_context.locations->getBinaryDir();
+        WrtUtilMakeDir(widgetBinPath);
+        std::string sourceDir = m_context.locations->getSourceDir();
+        WrtUtilMakeDir(sourceDir);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed) {
+        ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
+                   "Error during \
+                create external folder ");
+    }
+    Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
+    {
+        ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
+                   "Error during create external folder ");
+    }
+}
+
+void TaskFileManipulation::StartStep()
+{
+    _D("--------- <TaskFileManipulation> : START ----------");
+}
+
+void TaskFileManipulation::EndStep()
+{
+    _D("--------- <TaskFileManipulation> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_file_manipulation.h b/src_mobile/jobs/widget_install/task_file_manipulation.h
new file mode 100644 (file)
index 0000000..113ca72
--- /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    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_FILE_MANIPULATION_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_FILE_MANIPULATION_UPDATE_H
+
+#include <dpl/task.h>
+#include <app2ext_interface.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskFileManipulation :
+    public DPL::TaskDecl<TaskFileManipulation>
+{
+    InstallerContext& m_context;
+    app2ext_handle *m_extHandle;
+
+    // install internal location
+    void StepCheckInstallLocation();
+    void StepPrepareRootDirectory();
+    void StepUnzipWgtFile();
+    void StepAbortPrepareRootDirectory();
+    void StepLinkForPreload();
+    void StartStep();
+    void EndStep();
+
+    // install external location
+    void prepareExternalDir();
+
+  public:
+    TaskFileManipulation(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_FILE_MANIPULATION_H
diff --git a/src_mobile/jobs/widget_install/task_install_ospsvc.cpp b/src_mobile/jobs/widget_install/task_install_ospsvc.cpp
new file mode 100644 (file)
index 0000000..15923f9
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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_install_ospsvc.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task  install osp service
+ */
+#include "task_install_ospsvc.h"
+
+#include <unistd.h>
+#include <string>
+
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <fstream>
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/utils/bash_utils.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+const char* OSP_INSTALL_STR1 = "/usr/etc/package-manager/backend/tpk -iv ";
+const char* OSP_INSTALL_STR2 = " -p ";
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskInstallOspsvc::TaskInstallOspsvc(InstallerContext& context) :
+    DPL::TaskDecl<TaskInstallOspsvc>(this),
+    m_context(context)
+{
+    AddStep(&TaskInstallOspsvc::StartStep);
+    AddStep(&TaskInstallOspsvc::StepInstallOspService);
+    AddStep(&TaskInstallOspsvc::EndStep);
+}
+
+void TaskInstallOspsvc::StepInstallOspService()
+{
+    _D("Step: installation for osp service");
+
+    std::ostringstream commStr;
+    commStr << OSP_INSTALL_STR1<< BashUtils::escape_arg(
+        m_context.locations->getPackageInstallationDir())
+        << OSP_INSTALL_STR2 << m_context.certLevel;
+    _D("osp install command : %s", commStr.str().c_str());
+
+    char readBuf[MAX_BUF_SIZE];
+    FILE *fd;
+    fd = popen(commStr.str().c_str(), "r");
+    if (NULL == fd) {
+        _E("Failed to installtion osp service");
+        ThrowMsg(Exceptions::InstallOspsvcFailed,
+                 "Error occurs during\
+                install osp service");
+    }
+
+    if (fgets(readBuf, MAX_BUF_SIZE, fd) == NULL)
+    {
+        _E("Failed to installtion osp service.\
+                Inability of reading file.");
+        ThrowMsg(Exceptions::InstallOspsvcFailed,
+                "Error occurs during\
+                install osp service");
+    }
+    _D("return value : %s", readBuf);
+
+    int result = atoi(readBuf);
+    if (0 != result) {
+        ThrowMsg(Exceptions::InstallOspsvcFailed,
+                 "Error occurs during\
+                install osp service");
+    }
+
+    pclose(fd);
+}
+
+void TaskInstallOspsvc::StartStep()
+{
+    _D("--------- <TaskInstallOspsvc> : START ----------");
+}
+
+void TaskInstallOspsvc::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_INSTALL_OSPSVC,
+        "Installed Osp servcie");
+
+    _D("--------- <TaskInstallOspsvc> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_install_ospsvc.h b/src_mobile/jobs/widget_install/task_install_ospsvc.h
new file mode 100644 (file)
index 0000000..3e3a7e6
--- /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       task_install_ospsvc.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_INSTALL_OSPSVC_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_INSTALL_OSPSVC_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskInstallOspsvc : public DPL::TaskDecl<TaskInstallOspsvc>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+
+    void StepInstallOspService();
+
+    void StepAbortInstall();
+
+    void StartStep();
+    void EndStep();
+
+    // return callback
+    static int StatusCallback(
+        int req_id, const char *pkg_type, const char *pkg_name,
+        const char *key, const char *val, const void *pmsg,
+        void *priv_data);
+
+  public:
+    explicit TaskInstallOspsvc(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_INSTALL_OSPSVC_H_ */
diff --git a/src_mobile/jobs/widget_install/task_manifest_file.cpp b/src_mobile/jobs/widget_install/task_manifest_file.cpp
new file mode 100755 (executable)
index 0000000..12f19bf
--- /dev/null
@@ -0,0 +1,1315 @@
+/*
+ * 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_manifest_file.cpp
+ * @author  Pawel Sikorski (p.sikorski@samgsung.com)
+ * @version
+ * @brief
+ */
+
+//SYSTEM INCLUDES
+#include <unistd.h>
+#include <string>
+#include <dpl/assert.h>
+#include <dirent.h>
+#include <fstream>
+#include <ail.h>
+
+//WRT INCLUDES
+#include <widget_install/task_manifest_file.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <web_provider_livebox_info.h>
+#include <web_provider_plugin_info.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/file_input.h>
+#include <dpl/errno_string.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 <dpl/utils/wrt_utility.h>
+#include <map>
+#include <libxml_utils.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <dpl/localization/LanguageTagsProvider.h>
+#include <dpl/utils/path.h>
+
+#include <installer_log.h>
+
+#define DEFAULT_ICON_NAME   "icon.png"
+#define DEFAULT_PREVIEW_NAME   "preview.png"
+
+using namespace WrtDB;
+
+namespace {
+typedef std::map<DPL::String, DPL::String> LanguageTagMap;
+
+const char* const STR_TRUE = "true";
+const char* const STR_FALSE = "false";
+const char* const STR_NODISPLAY = "nodisplay";
+
+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;
+
+    _D("Trying to map language tag: %ls", langTag.c_str());
+    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;
+        _D("Mapping IANA Language tag to language tag: %ls -> %ls", langTag.c_str(), (*ret).c_str());
+    }
+
+    return ret;
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+const char * TaskManifestFile::encoding = "UTF-8";
+
+TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
+    DPL::TaskDecl<TaskManifestFile>(this),
+    m_context(inCont),
+    writer(NULL)
+{
+    if (m_context.isUpdateMode) {
+        // for widget update.
+        AddStep(&TaskManifestFile::stepBackupIconFiles);
+        AddStep(&TaskManifestFile::stepCopyIconFiles);
+        AddStep(&TaskManifestFile::stepCopyLiveboxFiles);
+        AddStep(&TaskManifestFile::stepCopyAccountIconFiles);
+        AddStep(&TaskManifestFile::stepCreateExecFile);
+        AddStep(&TaskManifestFile::stepCreateLinkNPPluginsFile);
+        AddStep(&TaskManifestFile::stepGenerateManifest);
+        AddAbortStep(&TaskManifestFile::stepAbortIconFiles);
+    } else {
+        AddStep(&TaskManifestFile::stepCopyIconFiles);
+        AddStep(&TaskManifestFile::stepCopyLiveboxFiles);
+        AddStep(&TaskManifestFile::stepCopyAccountIconFiles);
+        AddStep(&TaskManifestFile::stepCreateExecFile);
+        AddStep(&TaskManifestFile::stepCreateLinkNPPluginsFile);
+        AddStep(&TaskManifestFile::stepGenerateManifest);
+    }
+}
+
+TaskManifestFile::~TaskManifestFile()
+{}
+
+void TaskManifestFile::stepCreateExecFile()
+{
+    std::string exec = m_context.locations->getExecFile();
+    std::string clientExeStr = GlobalConfig::GetWrtClientExec();
+
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //default widget
+    std::stringstream postfix;
+    postfix << AppControlPrefix::PROCESS_PREFIX << 0;
+    std::string controlExec = exec;
+    controlExec.append(postfix.str());
+
+    errno = 0;
+    if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0)
+    {
+        int error = errno;
+        if (error)
+            _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+    }
+
+    // app-control widgets
+    unsigned int indexMax = 0;
+    FOREACH(it, m_context.widgetConfig.configInfo.appControlList) {
+        if (it->m_index > indexMax) {
+            indexMax = it->m_index;
+        }
+    }
+
+    for (std::size_t i = 1; i <= indexMax; ++i) {
+        std::stringstream postfix;
+        postfix << AppControlPrefix::PROCESS_PREFIX << i;
+        std::string controlExec = exec;
+        controlExec.append(postfix.str());
+        errno = 0;
+        if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+            }
+        }
+    }
+#else
+    //default widget
+    _D("link -s %s %s", clientExeStr.c_str(), exec.c_str());
+    errno = 0;
+    if (symlink(clientExeStr.c_str(), exec.c_str()) != 0)
+    {
+        int error = errno;
+        if (error)
+            _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+    }
+#endif
+    // creation of box symlink
+    ConfigParserData::LiveboxList& liveboxList =
+        m_context.widgetConfig.configInfo.m_livebox;
+    if (!liveboxList.empty()) {
+        std::string boxExec = "/usr/bin/WebProcess";
+        std::string boxSymlink = m_context.locations->getExecFile();
+        boxSymlink += ".d-box";
+
+        errno = 0;
+        if (symlink(boxExec.c_str(), boxSymlink.c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+            }
+        }
+    }
+
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_CREATE_EXECFILE,
+            "Widget execfile creation Finished");
+}
+
+void TaskManifestFile::stepCreateLinkNPPluginsFile()
+{
+    _D("stepCreateLinkNPPluginsFile");
+    if (0 == access(m_context.locations->getNPPluginsDir().c_str(), F_OK)) {
+        _D("This webapp has NPPlugins");
+        std::string pluginsExec = "/usr/bin/PluginProcess";
+        errno = 0;
+        if (symlink(pluginsExec.c_str(),
+                    m_context.locations->getNPPluginsExecFile().c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                _E("Failed to create symbolic link for npplugins : %ls",
+                        DPL::GetErrnoString(error).c_str());
+            }
+        }
+    }
+}
+
+void TaskManifestFile::stepCopyIconFiles()
+{
+    _D("CopyIconFiles");
+
+    //This function copies icon to desktop icon path. For each locale avaliable
+    //which there is at least one icon in widget for, icon file is copied.
+    //Coping prioritize last positions when coping. If there is several icons
+    //with given locale, the one, that will be copied, will be icon
+    //which is declared by <icon> tag later than the others in config.xml of
+    // widget
+
+    std::vector<Locale> generatedLocales;
+
+    WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
+        m_context.widgetConfig.localizationData.icons;
+
+    for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_iterator
+         icon = icons.begin();
+         icon != icons.end();
+         ++icon)
+    {
+        DPL::String src = icon->src;
+        FOREACH(locale, icon->availableLocales)
+        {
+            _D("Icon for locale: %ls is: %ls", (*locale).c_str(), src.c_str());
+
+            if (std::find(generatedLocales.begin(), generatedLocales.end(),
+                    *locale) != generatedLocales.end())
+            {
+                _D("Skipping - has that locale");
+                continue;
+            } else {
+                generatedLocales.push_back(*locale);
+            }
+
+            DPL::Utils::Path sourceFile(m_context.locations->getSourceDir());
+            if (!locale->empty()) {
+                sourceFile /= "locales";
+                sourceFile /= *locale;
+            }
+            sourceFile /= src;
+
+            DPL::Utils::Path targetFile(GlobalConfig::GetUserWidgetDesktopIconPath());
+            targetFile /= getIconTargetFilename(*locale, sourceFile.Extension());
+
+            if (m_context.widgetConfig.packagingType ==
+                WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+            {
+                m_context.locations->setIconTargetFilenameForLocale(
+                    targetFile.Fullpath());
+            }
+
+            _D("Copying icon: %s -> %s", sourceFile.Filename().c_str(), targetFile.Filename().c_str());
+
+            icon_list.push_back(targetFile.Fullpath());
+
+            Try
+            {
+                DPL::FileInput input(sourceFile.Fullpath());
+                DPL::FileOutput output(targetFile.Fullpath());
+                DPL::Copy(&input, &output);
+            }
+
+            Catch(DPL::FileInput::Exception::Base)
+            {
+                // Error while opening or closing source file
+                //ReThrowMsg(InstallerException::CopyIconFailed,
+                // sourceFile.str());
+                _E("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());
+                _E("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());
+                _E("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 TaskManifestFile::stepCopyLiveboxFiles()
+{
+    _D("Copy Livebox Files");
+
+    using namespace WrtDB;
+    ConfigParserData &data = m_context.widgetConfig.configInfo;
+    ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
+
+    if (liveBoxList.size() <= 0) {
+        return;
+    }
+
+    std::ostringstream sourceFile;
+    std::ostringstream targetFile;
+
+    FOREACH (boxIt, liveBoxList) {
+        ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+            (**boxIt).m_boxInfo.m_boxSize;
+        FOREACH (sizeIt, boxSizeList) {
+            std::string preview = DPL::ToUTF8String((*sizeIt).m_preview);
+            if (preview.empty()) {
+                continue;
+            }
+            sourceFile << m_context.locations->getSourceDir() << "/";
+            sourceFile << preview;
+            targetFile << m_context.locations->getSharedDataDir() << "/";
+            targetFile << (**boxIt).m_liveboxId << ".";
+            targetFile << DPL::ToUTF8String((*sizeIt).m_size) << "." << DEFAULT_PREVIEW_NAME;
+
+            copyFile(sourceFile.str(), targetFile.str());
+
+            // clear stream objects
+            sourceFile.str("");
+            targetFile.str("");
+        }
+        // check this livebox has icon element
+        std::string icon = DPL::ToUTF8String((**boxIt).m_icon);
+        if (icon.empty()) {
+            continue;
+        }
+        sourceFile << m_context.locations->getSourceDir() << "/";
+        sourceFile << icon;
+        targetFile << m_context.locations->getSharedDataDir() << "/";
+        targetFile << (**boxIt).m_liveboxId << "." << DEFAULT_ICON_NAME;
+
+        copyFile(sourceFile.str(), targetFile.str());
+
+        // clear stream objects
+        sourceFile.str("");
+        targetFile.str("");
+    }
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_COPY_LIVEBOX_FILES,
+        "Livebox files copy Finished");
+}
+
+void TaskManifestFile::stepCopyAccountIconFiles()
+{
+    _D("Copy Account icon files");
+    WrtDB::ConfigParserData::AccountProvider account =
+        m_context.widgetConfig.configInfo.accountProvider;
+
+    if (account.m_iconSet.empty()) {
+        _D("Widget doesn't contain Account");
+        return;
+    }
+
+    FOREACH(it, account.m_iconSet) {
+        std::string sourceFile = m_context.locations->getSourceDir() +
+                                 '/' +
+                                 DPL::ToUTF8String(it->second);
+        std::string targetFile = m_context.locations->getSharedResourceDir() +
+                                 '/' +
+                                 DPL::ToUTF8String(it->second);
+        copyFile(sourceFile, targetFile);
+    }
+}
+
+void TaskManifestFile::copyFile(const std::string& sourceFile,
+                                const std::string& targetFile)
+{
+    Try
+    {
+        DPL::FileInput input(sourceFile);
+        DPL::FileOutput output(targetFile);
+        DPL::Copy(&input, &output);
+    }
+    Catch(DPL::Exception)
+    {
+        _E("Failed to file copy. %s to %s", sourceFile.c_str(), targetFile.c_str());
+        ReThrowMsg(Exceptions::CopyIconFailed, "Error during file copy.");
+    }
+}
+
+bool TaskManifestFile::addBoxUiApplication(Manifest& manifest)
+{
+    UiApplication uiApp;
+    std::string postfix = ".d-box";
+    static bool isAdded = false;
+
+    Try
+    {
+        if (isAdded) {
+            _D("UiApplication for d-box is already added");
+            return false;
+        }
+        uiApp.setNodisplay(true);
+        uiApp.setTaskmanage(false);
+        uiApp.setMultiple(false);
+        setWidgetName(manifest, uiApp);
+        setWidgetIcons(uiApp);
+
+        // appid for box is like [webapp id].d-box
+        setWidgetIds(manifest, uiApp, postfix);
+        // executable path for box is like [app path]/bin/[webapp id].d-box
+        setWidgetExecPath(uiApp, postfix);
+        manifest.addUiApplication(uiApp);
+        isAdded = true;
+
+        return true;
+    }
+    Catch(DPL::Exception)
+    {
+        _E("Adding UiApplication on xml is failed.");
+        isAdded = false;
+        return false;
+    }
+}
+
+void TaskManifestFile::stepBackupIconFiles()
+{
+    _D("Backup Icon Files");
+
+    backup_dir << m_context.locations->getBackupDir() << "/";
+
+    backupIconFiles();
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_BACKUP_ICONFILE,
+        "New Widget icon file backup Finished");
+}
+
+void TaskManifestFile::stepAbortIconFiles()
+{
+    _D("Abrot Icon Files");
+    FOREACH(it, icon_list)
+    {
+        _D("Remove Update Icon : %s", (*it).c_str());
+        unlink((*it).c_str());
+    }
+
+    std::ostringstream b_icon_dir;
+    b_icon_dir << backup_dir.str() << "icons";
+
+    std::list<std::string> fileList;
+    getFileList(b_icon_dir.str().c_str(), fileList);
+
+    FOREACH(back_icon, fileList)
+    {
+        std::ostringstream res_file;
+        res_file << GlobalConfig::GetUserWidgetDesktopIconPath();
+        res_file << "/" << (*back_icon);
+
+        std::ostringstream backup_file;
+        backup_file << b_icon_dir.str() << "/" << (*back_icon);
+
+        Try
+        {
+            DPL::FileInput input(backup_file.str());
+            DPL::FileOutput output(res_file.str());
+            DPL::Copy(&input, &output);
+        }
+        Catch(DPL::FileInput::Exception::Base)
+        {
+            _E("Restoration icon File Failed. %s to %s", backup_file.str().c_str(), res_file.str().c_str());
+        }
+
+        Catch(DPL::FileOutput::Exception::Base)
+        {
+            _E("Restoration icon File Failed. %s to %s", backup_file.str().c_str(), res_file.str().c_str());
+        }
+        Catch(DPL::CopyFailed)
+        {
+            _E("Restoration icon File Failed. %s to %s", backup_file.str().c_str(), res_file.str().c_str());
+        }
+    }
+}
+
+DPL::String TaskManifestFile::getIconTargetFilename(
+    const DPL::String& languageTag, const std::string & ext) const
+{
+    DPL::OStringStream filename;
+    TizenAppId appid = m_context.widgetConfig.tzAppid;
+
+    filename << DPL::ToUTF8String(appid).c_str();
+
+    if (!languageTag.empty()) {
+        DPL::OptionalString tag = getLangTag(languageTag); // translate en ->
+                                                           // en_US etc
+        if (tag.IsNull()) {
+            tag = languageTag;
+        }
+        DPL::String locale =
+            LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+
+        if (locale.empty()) {
+            filename << L"." << languageTag;
+        } else {
+            filename << L"." << locale;
+        }
+    }
+
+    if(!ext.empty())
+    {
+        filename << L"." + DPL::FromUTF8String(ext);
+    }
+    return filename.str();
+}
+
+void TaskManifestFile::saveLocalizedKey(std::ofstream &file,
+                                        const DPL::String& key,
+                                        const DPL::String& languageTag)
+{
+    DPL::String locale =
+        LanguageTagsProvider::BCP47LanguageTagToLocale(languageTag);
+
+    file << key;
+    if (!locale.empty()) {
+        file << "[" << locale << "]";
+    }
+    file << "=";
+}
+
+void TaskManifestFile::backupIconFiles()
+{
+    _D("Backup Icon Files");
+
+    std::ostringstream b_icon_dir;
+    b_icon_dir << backup_dir.str() << "icons";
+
+    _D("Create icon backup folder : %s", b_icon_dir.str().c_str());
+    WrtUtilMakeDir(b_icon_dir.str());
+
+    std::list<std::string> fileList;
+    getFileList(GlobalConfig::GetUserWidgetDesktopIconPath(), fileList);
+    std::string appid = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+
+    FOREACH(it, fileList)
+    {
+        if (0 == (strncmp((*it).c_str(), appid.c_str(),
+                          strlen(appid.c_str()))))
+        {
+            std::ostringstream icon_file, backup_icon;
+            icon_file << GlobalConfig::GetUserWidgetDesktopIconPath();
+            icon_file << "/" << (*it);
+
+            backup_icon << b_icon_dir.str() << "/" << (*it);
+
+            _D("Backup icon file %s to %s", icon_file.str().c_str(), backup_icon.str().c_str());
+            Try
+            {
+                DPL::FileInput input(icon_file.str());
+                DPL::FileOutput output(backup_icon.str());
+                DPL::Copy(&input, &output);
+            }
+            Catch(DPL::FileInput::Exception::Base)
+            {
+                _E("Backup Desktop File Failed.");
+                ReThrowMsg(Exceptions::BackupFailed, icon_file.str());
+            }
+
+            Catch(DPL::FileOutput::Exception::Base)
+            {
+                _E("Backup Desktop File Failed.");
+                ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
+            }
+            Catch(DPL::CopyFailed)
+            {
+                _E("Backup Desktop File Failed.");
+                ReThrowMsg(Exceptions::BackupFailed, backup_icon.str());
+            }
+            unlink((*it).c_str());
+        }
+    }
+}
+
+void TaskManifestFile::getFileList(const char* path,
+                                   std::list<std::string> &list)
+{
+    DIR* dir = opendir(path);
+    if (!dir) {
+        _E("icon directory doesn't exist");
+        ThrowMsg(Exceptions::FileOperationFailed, path);
+    }
+
+    struct dirent entry;
+    struct dirent *result;
+    int return_code;
+    errno = 0;
+    for (return_code = readdir_r(dir, &entry, &result);
+            result != NULL && return_code == 0;
+            return_code = readdir_r(dir, &entry, &result))
+    {
+        if (strcmp(entry.d_name, ".") == 0 ||
+            strcmp(entry.d_name, "..") == 0)
+        {
+            continue;
+        }
+        std::string file_name = entry.d_name;
+        list.push_back(file_name);
+    }
+
+    if (return_code != 0 || errno != 0) {
+        _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
+    }
+
+    if (-1 == closedir(dir)) {
+        _E("Failed to close dir: %s with error: %s", path, DPL::GetErrnoString().c_str());
+    }
+}
+
+void TaskManifestFile::stepGenerateManifest()
+{
+    TizenPkgId pkgid = m_context.widgetConfig.tzPkgid;
+    manifest_name = pkgid + L".xml";
+    manifest_file += L"/tmp/" + manifest_name;
+
+    //libxml - init and check
+    LibxmlSingleton::Instance().init();
+
+    writeManifest(manifest_file);
+
+    std::ostringstream destFile;
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        destFile << WrtDB::GlobalConfig::GetPreloadManifestPath() << "/";
+    } else {
+        destFile << WrtDB::GlobalConfig::GetManifestPath() << "/";
+    }
+
+    destFile << DPL::ToUTF8String(manifest_name);
+    commit_manifest = destFile.str();
+    _D("Commiting manifest file : %s", commit_manifest.c_str());
+
+    commitManifest();
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_CREATE_MANIFEST,
+        "Widget Manifest Creation Finished");
+}
+
+void TaskManifestFile::commitManifest()
+{
+
+    if (!(m_context.mode.rootPath == InstallMode::RootPath::RO &&
+                m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+        _D("cp %ls %s", manifest_file.c_str(), commit_manifest.c_str());
+
+        DPL::FileInput input(DPL::ToUTF8String(manifest_file));
+        DPL::FileOutput output(commit_manifest);
+        DPL::Copy(&input, &output);
+        _D("Manifest writen to: %s", commit_manifest.c_str());
+
+        //removing temp file
+        unlink((DPL::ToUTF8String(manifest_file)).c_str());
+        manifest_file = DPL::FromUTF8String(commit_manifest);
+    }
+}
+
+void TaskManifestFile::writeManifest(const DPL::String & path)
+{
+    _D("Generating manifest file : %ls", path.c_str());
+    Manifest manifest;
+    UiApplication uiApp;
+
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //default widget content
+    std::stringstream postfix;
+    // index 0 is reserved
+    postfix << AppControlPrefix::PROCESS_PREFIX << 0;
+    setWidgetExecPath(uiApp, postfix.str());
+    setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
+    setWidgetIcons(uiApp);
+    setWidgetDescription(manifest);
+    setWidgetManifest(manifest);
+    setWidgetOtherInfo(uiApp);
+    setAppCategory(uiApp);
+    setMetadata(uiApp);
+    // move to the last of this procedure
+    //setLiveBoxInfo(manifest);
+    setAccount(manifest);
+    setPrivilege(manifest);
+    manifest.addUiApplication(uiApp);
+
+    //app-control content
+    ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+    FOREACH(it, appControlList) {
+        UiApplication uiApp;
+
+        uiApp.setTaskmanage(true);
+        uiApp.setNodisplay(true);
+#ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
+        uiApp.setTaskmanage(ConfigParserData::AppControlInfo::Disposition::INLINE != it->m_disposition);
+        uiApp.setMultiple(ConfigParserData::AppControlInfo::Disposition::INLINE == it->m_disposition);
+#endif
+        std::stringstream postfix;
+        postfix << AppControlPrefix::PROCESS_PREFIX << it->m_index;
+        setWidgetExecPath(uiApp, postfix.str());
+        setWidgetName(manifest, uiApp);
+        setWidgetIds(manifest, uiApp);
+        setWidgetIcons(uiApp);
+        setAppControlInfo(uiApp, *it);
+        setAppCategory(uiApp);
+        setMetadata(uiApp);
+        manifest.addUiApplication(uiApp);
+    }
+    // TODO: Must fix again with right method
+    // The mainapp attiribute must be set
+    // when there are multiple uiapps in mainfest
+    setLiveBoxInfo(manifest);
+#else
+    //default widget content
+    setWidgetExecPath(uiApp);
+    setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
+    setWidgetIcons(uiApp);
+    setWidgetDescription(manifest);
+    setWidgetManifest(manifest);
+    setWidgetOtherInfo(uiApp);
+    setAppControlsInfo(uiApp);
+    setAppCategory(uiApp);
+    setMetadata(uiApp);
+    // move to the last of this procedure
+    //setLiveBoxInfo(manifest);
+    setAccount(manifest);
+    setPrivilege(manifest);
+
+    manifest.addUiApplication(uiApp);
+    // TODO: Must fix again with right method
+    // The mainapp attiribute must be set
+    // when there are multiple uiapps in mainfest
+    setLiveBoxInfo(manifest);
+#endif
+
+    manifest.generate(path);
+    _D("Manifest file serialized");
+}
+
+void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp,
+                                         const std::string &postfix)
+{
+    std::string exec = m_context.locations->getExecFile();
+    if (!postfix.empty()) {
+        exec.append(postfix);
+    }
+    _D("exec = %s", exec.c_str());
+    uiApp.setExec(DPL::FromASCIIString(exec));
+}
+
+void TaskManifestFile::setWidgetName(Manifest & manifest,
+                                     UiApplication & uiApp)
+{
+    bool defaultNameSaved = false;
+
+    DPL::OptionalString defaultLocale =
+        m_context.widgetConfig.configInfo.defaultlocale;
+    std::pair<DPL::String,
+              WrtDB::ConfigParserData::LocalizedData> defaultLocalizedData;
+    //labels
+    FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
+        if (tag.IsNull()) {
+            tag = i;
+        }
+        DPL::OptionalString name = localizedData->second.name;
+        generateWidgetName(manifest, uiApp, tag, name, defaultNameSaved);
+
+        //store default locale localized data
+        if (!!defaultLocale && defaultLocale == i) {
+            defaultLocalizedData = *localizedData;
+        }
+    }
+
+    if (!!defaultLocale && !defaultNameSaved) {
+        DPL::OptionalString name = defaultLocalizedData.second.name;
+        generateWidgetName(manifest,
+                           uiApp,
+                           DPL::OptionalString::Null,
+                           name,
+                           defaultNameSaved);
+    }
+}
+
+void TaskManifestFile::setWidgetIds(Manifest & manifest,
+                                    UiApplication & uiApp,
+                                    const std::string &postfix)
+{
+    //appid
+    TizenAppId appid = m_context.widgetConfig.tzAppid;
+    if (!postfix.empty()) {
+        appid = DPL::FromUTF8String(DPL::ToUTF8String(appid).append(postfix));
+    }
+    uiApp.setAppid(appid);
+
+    //extraid
+    if (!!m_context.widgetConfig.guid) {
+        uiApp.setExtraid(*m_context.widgetConfig.guid);
+    } else {
+        if (!appid.empty()) {
+            uiApp.setExtraid(DPL::String(L"http://") + appid);
+        }
+    }
+
+    //type
+    uiApp.setType(DPL::FromASCIIString("webapp"));
+    manifest.setType(L"wgt");
+}
+
+void TaskManifestFile::generateWidgetName(Manifest & manifest,
+                                          UiApplication &uiApp,
+                                          const DPL::OptionalString& tag,
+                                          DPL::OptionalString name,
+                                          bool & defaultNameSaved)
+{
+    if (!!name) {
+        if (!!tag) {
+            DPL::String locale =
+                LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+
+            if (!locale.empty()) {
+                uiApp.addLabel(LabelType(*name, *tag));
+            } else {
+                uiApp.addLabel(LabelType(*name));
+                manifest.addLabel(LabelType(*name));
+            }
+        } else {
+            defaultNameSaved = true;
+            uiApp.addLabel(LabelType(*name));
+            manifest.addLabel(LabelType(*name));
+        }
+    }
+}
+
+void TaskManifestFile::setWidgetIcons(UiApplication & uiApp)
+{
+    //TODO this file will need to be updated when user locale preferences
+    //changes.
+    bool defaultIconSaved = false;
+
+    DPL::OptionalString defaultLocale =
+        m_context.widgetConfig.configInfo.defaultlocale;
+
+    std::vector<Locale> generatedLocales;
+    WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
+        m_context.widgetConfig.localizationData.icons;
+
+    for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_iterator
+         icon = icons.begin();
+         icon != icons.end();
+         ++icon)
+    {
+        FOREACH(locale, icon->availableLocales)
+        {
+            if (std::find(generatedLocales.begin(), generatedLocales.end(),
+                          *locale) != generatedLocales.end())
+            {
+                _D("Skipping - has that locale - already in manifest");
+                continue;
+            } else {
+                generatedLocales.push_back(*locale);
+            }
+
+            DPL::OptionalString tag = getLangTag(*locale); // translate en ->
+                                                           // en_US etc
+            if (tag.IsNull()) {
+                tag = *locale;
+            }
+
+            generateWidgetIcon(uiApp, tag, *locale, DPL::Utils::Path(icon->src).Extension(), defaultIconSaved);
+        }
+    }
+    if (!!defaultLocale && !defaultIconSaved) {
+        generateWidgetIcon(uiApp, DPL::OptionalString::Null,
+                           DPL::String(),
+                           std::string(),
+                           defaultIconSaved);
+    }
+}
+
+void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp,
+                                          const DPL::OptionalString& tag,
+                                          const DPL::String& language,
+                                          const std::string & extension,
+                                          bool & defaultIconSaved)
+{
+    DPL::String locale;
+    if (!!tag) {
+        locale = LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+    } else {
+        defaultIconSaved = true;
+    }
+
+    DPL::String iconText;
+    iconText += getIconTargetFilename(language, extension);
+
+    if (!locale.empty()) {
+        uiApp.addIcon(IconType(iconText, locale));
+    } else {
+        uiApp.addIcon(IconType(iconText));
+    }
+    std::ostringstream iconPath;
+    iconPath << GlobalConfig::GetUserWidgetDesktopIconPath() << "/";
+    iconPath << getIconTargetFilename(locale, extension);
+    m_context.job->SendProgressIconPath(iconPath.str());
+}
+
+void TaskManifestFile::setWidgetDescription(Manifest & manifest)
+{
+    FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
+        if (tag.IsNull()) {
+            tag = i;
+        }
+        DPL::OptionalString description = localizedData->second.description;
+        generateWidgetDescription(manifest, tag, description);
+    }
+}
+
+void TaskManifestFile::generateWidgetDescription(Manifest & manifest,
+                                                 const DPL::OptionalString& tag,
+                                                  DPL::OptionalString description)
+{
+    if (!!description) {
+        if (!!tag) {
+            DPL::String locale =
+                LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+            if (!locale.empty()) {
+                manifest.addDescription(DescriptionType(*description, locale));
+            } else {
+                manifest.addDescription(DescriptionType(*description));
+            }
+        } else {
+            manifest.addDescription(DescriptionType(*description));
+        }
+    }
+}
+
+void TaskManifestFile::setWidgetManifest(Manifest & manifest)
+{
+    manifest.setPackage(m_context.widgetConfig.tzPkgid);
+
+    if (!!m_context.widgetConfig.version) {
+        manifest.setVersion(*m_context.widgetConfig.version);
+    }
+    DPL::String email = (!!m_context.widgetConfig.configInfo.authorEmail ?
+                         *m_context.widgetConfig.configInfo.authorEmail : L"");
+    DPL::String href = (!!m_context.widgetConfig.configInfo.authorHref ?
+                        *m_context.widgetConfig.configInfo.authorHref : L"");
+    DPL::String name = (!!m_context.widgetConfig.configInfo.authorName ?
+                        *m_context.widgetConfig.configInfo.authorName : L"");
+    manifest.addAuthor(Author(email, href, L"", name));
+
+    if (!m_context.callerPkgId.empty()) {
+        manifest.setStoreClientId(m_context.callerPkgId);
+    }
+}
+
+void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
+{
+    FOREACH(it, m_context.widgetConfig.configInfo.settingsList)
+    {
+        if (!strcmp(DPL::ToUTF8String(it->m_name).c_str(), STR_NODISPLAY)) {
+            if (!strcmp(DPL::ToUTF8String(it->m_value).c_str(), STR_TRUE)) {
+                uiApp.setNodisplay(true);
+                uiApp.setTaskmanage(false);
+            } else {
+                uiApp.setNodisplay(false);
+                uiApp.setTaskmanage(true);
+            }
+        }
+    }
+    //TODO
+    //There is no "X-TIZEN-PackageType=wgt"
+    //There is no X-TIZEN-PackageID in manifest "X-TIZEN-PackageID=" <<
+    // DPL::ToUTF8String(*widgetID).c_str()
+    //There is no Comment in pkgmgr "Comment=Widget application"
+    //that were in desktop file
+}
+
+void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp)
+{
+    WrtDB::ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+
+    if (appControlList.empty()) {
+        _D("Widget doesn't contain app control");
+        return;
+    }
+
+     // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    FOREACH(it, appControlList) {
+        setAppControlInfo(uiApp, *it);
+    }
+}
+
+void TaskManifestFile::setAppControlInfo(UiApplication & uiApp,
+                                         const WrtDB::ConfigParserData::AppControlInfo & service)
+{
+    // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    AppControl appControl;
+    if (!service.m_operation.empty()) {
+        appControl.addOperation(service.m_operation); //TODO: encapsulation?
+    }
+    if (!service.m_uriList.empty()) {
+        FOREACH(uri, service.m_uriList) {
+            appControl.addUri(*uri);
+        }
+    }
+    if (!service.m_mimeList.empty()) {
+        FOREACH(mime, service.m_mimeList) {
+            appControl.addMime(*mime);
+        }
+    }
+    uiApp.addAppControl(appControl);
+}
+
+void TaskManifestFile::setAppCategory(UiApplication &uiApp)
+{
+    WrtDB::ConfigParserData::CategoryList categoryList =
+        m_context.widgetConfig.configInfo.categoryList;
+
+    if (categoryList.empty()) {
+        _D("Widget doesn't contain application category");
+        return;
+    }
+    FOREACH(it, categoryList) {
+        if (!(*it).empty()) {
+            uiApp.addAppCategory(*it);
+        }
+    }
+}
+
+void TaskManifestFile::setMetadata(UiApplication &uiApp)
+{
+    WrtDB::ConfigParserData::MetadataList metadataList =
+        m_context.widgetConfig.configInfo.metadataList;
+
+    if (metadataList.empty()) {
+        _D("Web application doesn't contain metadata");
+        return;
+    }
+    FOREACH(it, metadataList) {
+        MetadataType metadataType(it->key, it->value);
+        uiApp.addMetadata(metadataType);
+    }
+}
+
+void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
+{
+    ConfigParserData::LiveboxList& liveboxList =
+        m_context.widgetConfig.configInfo.m_livebox;
+
+    if (liveboxList.empty()) {
+        _D("no livebox");
+        return;
+    }
+
+    if (!addBoxUiApplication(manifest)) {
+        _D("error during adding UiApplication for d-box");
+        return;
+    }
+
+    FOREACH(it, liveboxList) {
+        _D("setLiveBoxInfo");
+        LiveBoxInfo liveBox;
+        DPL::Optional<WrtDB::ConfigParserData::LiveboxInfo> ConfigInfo = *it;
+        DPL::String appid = m_context.widgetConfig.tzAppid;
+
+        if (ConfigInfo->m_liveboxId != L"") {
+            size_t found = ConfigInfo->m_liveboxId.find_last_of(L".");
+            if (found != std::string::npos) {
+                if (0 == ConfigInfo->m_liveboxId.compare(0, found, appid)) {
+                    liveBox.setLiveboxId(ConfigInfo->m_liveboxId);
+                } else {
+                    DPL::String liveboxId =
+                        appid + DPL::String(L".") + ConfigInfo->m_liveboxId;
+                    liveBox.setLiveboxId(liveboxId);
+                }
+            } else {
+                DPL::String liveboxId =
+                    appid + DPL::String(L".") + ConfigInfo->m_liveboxId;
+                liveBox.setLiveboxId(liveboxId);
+            }
+        }
+
+        if (ConfigInfo->m_primary != L"") {
+            liveBox.setPrimary(ConfigInfo->m_primary);
+        }
+
+        if (ConfigInfo->m_updatePeriod != L"") {
+            liveBox.setUpdatePeriod(ConfigInfo->m_updatePeriod);
+        }
+
+        std::list<std::pair<DPL::String, DPL::String> > boxLabelList;
+        if (!ConfigInfo->m_label.empty()) {
+            FOREACH(im, ConfigInfo->m_label) {
+                std::pair<DPL::String, DPL::String> boxSize;
+                Locale i = (*im).first;
+                // translate en -> en_US etc
+                DPL::OptionalString tag = getLangTag(i);
+                if (tag.IsNull()) {
+                    tag = i;
+                }
+                boxSize.first = (*tag);
+                boxSize.second = (*im).second;
+                boxLabelList.push_back(boxSize);
+            }
+            liveBox.setLabel(boxLabelList);
+        }
+
+        DPL::String defaultLocale =
+            DPL::FromUTF8String(m_context.locations->getPackageInstallationDir()) +
+            DPL::String(L"/res/wgt/");
+
+        if (ConfigInfo->m_icon != L"") {
+            DPL::String icon =
+                DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
+                DPL::String(L"/") +
+                ConfigInfo->m_liveboxId + DPL::String(L".icon.png");
+            liveBox.setIcon(icon);
+        }
+
+        if (ConfigInfo->m_boxInfo.m_boxSrc.empty() ||
+            ConfigInfo->m_boxInfo.m_boxSize.empty())
+        {
+            _D("Widget doesn't contain box");
+            return;
+        } else {
+            BoxInfoType box;
+            if (!ConfigInfo->m_boxInfo.m_boxSrc.empty()) {
+                if ((0 == ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 4, L"http"))
+                    || (0 ==
+                        ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 5, L"https")))
+                {
+                    box.boxSrc = ConfigInfo->m_boxInfo.m_boxSrc;
+                } else {
+                    box.boxSrc = defaultLocale + ConfigInfo->m_boxInfo.m_boxSrc;
+                }
+            }
+
+            if (ConfigInfo->m_boxInfo.m_boxMouseEvent == L"true") {
+                std::string boxType;
+                if (ConfigInfo->m_type == L"") {
+                    // in case of default livebox
+                    boxType = web_provider_livebox_get_default_type();
+                } else {
+                    boxType = DPL::ToUTF8String(ConfigInfo->m_type);
+                }
+
+                int box_scrollable =
+                    web_provider_plugin_get_box_scrollable(boxType.c_str());
+
+                if (box_scrollable) {
+                    box.boxMouseEvent = L"true";
+                } else {
+                    box.boxMouseEvent = L"false";
+                }
+            } else {
+                box.boxMouseEvent = L"false";
+            }
+
+            if (ConfigInfo->m_boxInfo.m_boxTouchEffect == L"true") {
+                box.boxTouchEffect = L"true";
+            } else {
+                box.boxTouchEffect= L"false";
+            }
+
+            ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+                ConfigInfo->m_boxInfo.m_boxSize;
+            FOREACH(it, boxSizeList) {
+                if (!(*it).m_preview.empty()) {
+                    (*it).m_preview =
+                        DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
+                        DPL::String(L"/") +
+                        ConfigInfo->m_liveboxId + DPL::String(L".") +
+                        (*it).m_size + DPL::String(L".preview.png");
+                }
+                box.boxSize.push_back((*it));
+            }
+
+            if (!ConfigInfo->m_boxInfo.m_pdSrc.empty()
+                && !ConfigInfo->m_boxInfo.m_pdWidth.empty()
+                && !ConfigInfo->m_boxInfo.m_pdHeight.empty())
+            {
+                if ((0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 4, L"http"))
+                    || (0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 5, L"https")))
+                {
+                    box.pdSrc = ConfigInfo->m_boxInfo.m_pdSrc;
+                } else {
+                    box.pdSrc = defaultLocale + ConfigInfo->m_boxInfo.m_pdSrc;
+                }
+                box.pdWidth = ConfigInfo->m_boxInfo.m_pdWidth;
+                box.pdHeight = ConfigInfo->m_boxInfo.m_pdHeight;
+            }
+            liveBox.setBox(box);
+        }
+        manifest.addLivebox(liveBox);
+    }
+}
+
+void TaskManifestFile::setAccount(Manifest& manifest)
+{
+    WrtDB::ConfigParserData::AccountProvider account =
+        m_context.widgetConfig.configInfo.accountProvider;
+
+    AccountProviderType provider;
+
+    if (account.m_iconSet.empty()) {
+        _D("Widget doesn't contain Account");
+        return;
+    }
+    if (account.m_multiAccountSupport) {
+        provider.multiAccount = L"true";
+    } else {
+        provider.multiAccount = L"false";
+    }
+    provider.appid = m_context.widgetConfig.tzAppid;
+
+    FOREACH(it, account.m_iconSet) {
+        std::pair<DPL::String, DPL::String> icon;
+
+        if (it->first == ConfigParserData::IconSectionType::DefaultIcon) {
+            icon.first = L"account";
+        } else if (it->first == ConfigParserData::IconSectionType::SmallIcon) {
+            icon.first = L"account-small";
+        }
+
+        // account manifest requires absolute path for icon
+        // /opt/apps/[package]/shared/res/[icon_path]
+        icon.second = DPL::FromUTF8String(m_context.locations->getSharedResourceDir()) +
+                      DPL::String(L"/") +
+                      it->second;
+        provider.icon.push_back(icon);
+    }
+
+    FOREACH(it, account.m_displayNameSet) {
+        provider.name.push_back(LabelType(it->second, it->first));
+    }
+
+    FOREACH(it, account.m_capabilityList) {
+        provider.capability.push_back(*it);
+    }
+
+    Account accountInfo;
+    accountInfo.addAccountProvider(provider);
+    manifest.addAccount(accountInfo);
+}
+
+void TaskManifestFile::setPrivilege(Manifest& manifest)
+{
+    WrtDB::ConfigParserData::PrivilegeList privileges =
+        m_context.widgetConfig.configInfo.privilegeList;
+
+    PrivilegeType privilege;
+
+    FOREACH(it, privileges)
+    {
+        privilege.addPrivilegeName(it->name);
+    }
+
+    manifest.addPrivileges(privilege);
+}
+
+void TaskManifestFile::StartStep()
+{
+
+}
+
+void TaskManifestFile::EndStep()
+{
+
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_manifest_file.h b/src_mobile/jobs/widget_install/task_manifest_file.h
new file mode 100644 (file)
index 0000000..afcb00d
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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_manifest_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>
+
+#include <libxml2/libxml/xmlwriter.h>
+
+#include <libxml_utils.h>
+#include <widget_install/manifest.h>
+#include <dpl/localization/localization_utils.h>
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskManifestFile :
+    public DPL::TaskDecl<TaskManifestFile>
+{
+  public:
+
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, ManifestValidationError)
+    DECLARE_EXCEPTION_TYPE(Base, ManifestParsingError)
+
+    TaskManifestFile(InstallerContext &inCont);
+    virtual ~TaskManifestFile();
+
+  private:
+    //context data
+    InstallerContext &m_context;
+
+    //TODO stepAbort
+    //steps
+    void stepCreateExecFile();
+    void stepCopyIconFiles();
+    void stepCopyLiveboxFiles();
+    void stepCopyAccountIconFiles();
+    void stepGenerateManifest();
+    void stepCreateLinkNPPluginsFile();
+
+    void stepAbortParseManifest();
+
+    //For widget update
+    void stepBackupIconFiles();
+    void stepAbortIconFiles();
+
+    void StartStep();
+    void EndStep();
+
+    //private data
+    std::list<std::string> icon_list; //TODO: this should be registered as
+                                      // external files
+    std::ostringstream backup_dir;
+    xmlTextWriterPtr writer;
+    DPL::String manifest_name;
+    DPL::String manifest_file;
+    std::string commit_manifest;
+
+    //private methods
+
+    void writeManifest(const DPL::String & path);
+    void commitManifest();
+
+    void setWidgetExecPath(UiApplication & uiApp,
+                           const std::string &postfix = std::string());
+    void setWidgetName(Manifest & manifest,
+                       UiApplication & uiApp);
+    void setWidgetIds(Manifest & manifest,
+                       UiApplication & uiApp,
+                       const std::string &postfix = std::string());
+    void setWidgetIcons(UiApplication & uiApp);
+    void setWidgetDescription(Manifest & manifest);
+    void setWidgetManifest(Manifest & manifest);
+    void setWidgetOtherInfo(UiApplication & uiApp);
+    void setAppControlsInfo(UiApplication & uiApp);
+    void setAppControlInfo(UiApplication & uiApp,
+                           const WrtDB::ConfigParserData::AppControlInfo & service);
+    void setAppCategory(UiApplication & uiApp);
+    void setMetadata(UiApplication & uiApp);
+    void setLiveBoxInfo(Manifest& manifest);
+    void setAccount(Manifest& uiApp);
+    void setPrivilege(Manifest& manifest);
+
+    void generateWidgetName(Manifest & manifest,
+                            UiApplication &uiApp,
+                            const DPL::OptionalString& tag,
+                            DPL::OptionalString name,
+                            bool & defaultNameSaved);
+    void generateWidgetDescription(Manifest & manifest,
+                                   const DPL::OptionalString& tag,
+                                   DPL::OptionalString description);
+    void generateWidgetIcon(UiApplication & uiApp,
+                            const DPL::OptionalString& tag,
+                            const DPL::String& language, const std::string &extension,
+                            bool & defaultIconSaved);
+    void copyFile(const std::string& sourceFile,
+                  const std::string& targetFile);
+    bool addBoxUiApplication(Manifest& manifest);
+
+    //for widget update
+    void backupIconFiles();
+    void getFileList(const char* path, std::list<std::string> &list);
+    DPL::String getIconTargetFilename(const DPL::String& languageTag,
+                                      const std::string & ext) const;
+
+    static void saveLocalizedKey(std::ofstream &file,
+                                 const DPL::String& key,
+                                 const DPL::String& languageTag);
+
+    static const char * encoding;
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DESKTOP_FILE_H */
diff --git a/src_mobile/jobs/widget_install/task_pkg_info_update.cpp b/src_mobile/jobs/widget_install/task_pkg_info_update.cpp
new file mode 100644 (file)
index 0000000..4bd0898
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * 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_pkg_info_update.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task information about package
+ * update
+ */
+#include "task_pkg_info_update.h"
+
+#include <unistd.h>
+#include <string>
+
+#include <fstream>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/foreach.h>
+#include <dpl/sstream.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <pkgmgr_installer.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <vcore/CryptoHash.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskPkgInfoUpdate::TaskPkgInfoUpdate(InstallerContext& context) :
+    DPL::TaskDecl<TaskPkgInfoUpdate>(this),
+    m_context(context)
+{
+    AddStep(&TaskPkgInfoUpdate::StartStep);
+    AddStep(&TaskPkgInfoUpdate::StepPkgInfo);
+    AddStep(&TaskPkgInfoUpdate::StepSetCertiInfo);
+    AddStep(&TaskPkgInfoUpdate::EndStep);
+    AddStep(&TaskPkgInfoUpdate::StepSetEndofInstallation);
+
+    AddAbortStep(&TaskPkgInfoUpdate::StepAbortCertiInfo);
+    AddAbortStep(&TaskPkgInfoUpdate::stepAbortParseManifest);
+}
+
+void TaskPkgInfoUpdate::StepPkgInfo()
+{
+    int code = 0;
+    char* updateTags[3] = {NULL, };
+
+    char preloadTrue[] = "preload=true";
+    char removableTrue[] = "removable=true";
+    char removableFalse[] = "removable=false";
+
+    if (InstallMode::InstallTime::CSC == m_context.mode.installTime) {
+        updateTags[0] = preloadTrue;
+        if (m_context.mode.removable) {
+            updateTags[1] = removableTrue;
+        } else {
+            updateTags[1] = removableFalse;
+        }
+        updateTags[2] = NULL;
+    }
+
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        m_manifest += "/usr/share/packages/";
+    } else {
+        m_manifest += "/opt/share/packages/";
+    }
+    m_manifest += DPL::ToUTF8String(m_context.widgetConfig.tzPkgid) + ".xml";
+    _D("manifest file : %s", m_manifest.c_str());
+
+    if (m_context.isUpdateMode || (
+                m_context.mode.rootPath == InstallMode::RootPath::RO
+                && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+
+        code = pkgmgr_parser_parse_manifest_for_upgrade(
+                m_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
+
+        if (code != 0) {
+            _E("Manifest parser error: %d", code);
+            ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
+        }
+    } else {
+        code = pkgmgr_parser_parse_manifest_for_installation(
+                m_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
+
+        if (code != 0) {
+            _E("Manifest parser error: %d", code);
+            ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
+        }
+    }
+
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_PKGINFO_UPDATE,
+            "Manifest Update Finished");
+    _D("Manifest parsed");
+}
+
+void TaskPkgInfoUpdate::StepSetCertiInfo()
+{
+    _D("StepSetCertiInfo");
+
+    if (pkgmgr_installer_create_certinfo_set_handle(&m_pkgHandle) < 0) {
+        _E("pkgmgrInstallerCreateCertinfoSetHandle fail");
+        ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                 "Failed to create certificate handle");
+    }
+
+    SetCertiInfo(SIGNATURE_AUTHOR);
+    SetCertiInfo(SIGNATURE_DISTRIBUTOR);
+
+    if ((pkgmgr_installer_save_certinfo(
+             const_cast<char*>(DPL::ToUTF8String(
+                                   m_context.widgetConfig.tzPkgid).c_str()),
+             m_pkgHandle)) < 0)
+    {
+        _E("pkgmgrInstallerSaveCertinfo fail");
+        ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                 "Failed to Installer Save Certinfo");
+    } else {
+        _D("Succeed to save Certinfo");
+    }
+
+    if (pkgmgr_installer_destroy_certinfo_set_handle(m_pkgHandle) < 0) {
+        _E("pkgmgrInstallerDestroyCertinfoSetHandle fail");
+    }
+}
+
+void TaskPkgInfoUpdate::SetCertiInfo(int source)
+{
+    _D("Set CertiInfo to pkgmgr : %d", source);
+    CertificateChainList certificateChainList;
+    m_context.widgetSecurity.getCertificateChainList(certificateChainList,
+            (CertificateSource)source);
+
+    FOREACH(it, certificateChainList)
+    {
+        _D("Insert certinfo to pkgmgr structure");
+
+        ValidationCore::CertificateCollection chain;
+
+        if (false == chain.load(*it)) {
+            _E("Chain is broken");
+            ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                     "Failed to Installer Save Certinfo");
+        }
+
+        if (!chain.sort()) {
+            _E("Chain failed at sorting");
+        }
+
+        ValidationCore::CertificateList list = chain.getCertificateList();
+
+        FOREACH(certIt, list)
+        {
+            pkgmgr_instcert_type instCertType;
+
+            if (source == SIGNATURE_DISTRIBUTOR) {
+                bool distributor1 = false;
+                if (!(*certIt)->getCommonName().IsNull()) {
+                    std::string
+                        Name(DPL::ToUTF8String(*(*certIt)->getCommonName()));
+                    std::string tizenStr("Tizen");
+                    if (0 == Name.compare(0, tizenStr.length(), tizenStr)) {
+                        distributor1 = true;
+                    }
+                }
+
+                if (distributor1) {
+                    _D("Set SIGNATURE_DISTRIBUTOR");
+                    if ((*certIt)->isRootCert()) {
+                        instCertType = PM_SET_DISTRIBUTOR_ROOT_CERT;
+                    } else {
+                        if ((*certIt)->isCA()) {
+                            instCertType = PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT;
+                        } else {
+                            instCertType = PM_SET_DISTRIBUTOR_SIGNER_CERT;
+                        }
+                    }
+                } else {
+                    _D("Set SIGNATURE_DISTRIBUTOR2");
+                    if ((*certIt)->isRootCert()) {
+                        instCertType = PM_SET_DISTRIBUTOR2_ROOT_CERT;
+                    } else {
+                        if ((*certIt)->isCA()) {
+                            instCertType = PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT;
+                        } else {
+                            instCertType = PM_SET_DISTRIBUTOR2_SIGNER_CERT;
+                        }
+                    }
+                }
+            } else {
+                _D("set SIGNATURE_AUTHOR");
+                if ((*certIt)->isRootCert()) {
+                    instCertType = PM_SET_AUTHOR_ROOT_CERT;
+                } else {
+                    if ((*certIt)->isCA()) {
+                        instCertType = PM_SET_AUTHOR_INTERMEDIATE_CERT;
+                    } else {
+                        instCertType = PM_SET_AUTHOR_SIGNER_CERT;
+                    }
+                }
+            }
+            _D("cert type : %d", instCertType);
+            if ((pkgmgr_installer_set_cert_value(
+                     m_pkgHandle,
+                     instCertType,
+                     const_cast<char*>(((*certIt)->getBase64()).c_str()))) < 0)
+            {
+                _E("pkgmgrInstallerSetCertValue fail");
+                ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                         "Failed to Set CertValue");
+            }
+        }
+    }
+}
+
+void TaskPkgInfoUpdate::StepAbortCertiInfo()
+{
+    if ((pkgmgr_installer_delete_certinfo(
+             const_cast<char*>(DPL::ToUTF8String(
+                                   m_context.widgetConfig.tzPkgid).c_str()))) <
+        0)
+    {
+        _E("pkgmgr_installer_delete_certinfo fail");
+    }
+}
+
+void TaskPkgInfoUpdate::StartStep()
+{
+    _D("--------- <TaskPkgInfoUpdate> : START ----------");
+}
+
+void TaskPkgInfoUpdate::EndStep()
+{
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_SET_CERTINFO,
+            "Save certinfo to pkgmgr");
+
+    _D("--------- <TaskPkgInfoUpdate> : END ----------");
+}
+
+void TaskPkgInfoUpdate::stepAbortParseManifest()
+{
+    _E("[Parse Manifest] Abroting....");
+
+    int code = pkgmgr_parser_parse_manifest_for_uninstallation(
+            m_manifest.c_str(), NULL);
+
+    if (0 != code) {
+        _W("Manifest parser error: %d", code);
+        ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
+    }
+    int ret = unlink(m_manifest.c_str());
+    if (0 != ret) {
+        _W("No manifest file found: %s", m_manifest.c_str());
+    }
+}
+
+void TaskPkgInfoUpdate::StepSetEndofInstallation()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_END,
+        "End installation");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_pkg_info_update.h b/src_mobile/jobs/widget_install/task_pkg_info_update.h
new file mode 100644 (file)
index 0000000..e1e9235
--- /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       task_pkg_info_update.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_PKG_INFO_UPDATE_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_PKG_INFO_UPDATE_H_
+
+#include <dpl/task.h>
+#include <string>
+#include <pkgmgr_installer.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskPkgInfoUpdate : public DPL::TaskDecl<TaskPkgInfoUpdate>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+
+    void StepPkgInfo();
+    void StepSetCertiInfo();
+    void SetCertiInfo(int source);
+    void StepSetEndofInstallation();
+
+    void stepAbortParseManifest();
+    void StepAbortCertiInfo();
+
+    void StartStep();
+    void EndStep();
+
+    pkgmgr_instcertinfo_h m_pkgHandle;
+    std::string m_manifest;
+
+  public:
+    explicit TaskPkgInfoUpdate(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_PKG_INFO_UPDATE_H_ */
diff --git a/src_mobile/jobs/widget_install/task_prepare_files.cpp b/src_mobile/jobs/widget_install/task_prepare_files.cpp
new file mode 100644 (file)
index 0000000..55791f4
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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_generate_config.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include "task_prepare_files.h"
+#include <memory>
+#include <string>
+#include <iostream>
+#include <dpl/file_output.h>
+#include <dpl/file_input.h>
+#include <dpl/copy.h>
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <dpl/foreach.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install_errors.h>
+#include <task_commons.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskPrepareFiles::TaskPrepareFiles(InstallerContext &installerContext) :
+    DPL::TaskDecl<TaskPrepareFiles>(this),
+    m_installerContext(installerContext)
+{
+    AddStep(&TaskPrepareFiles::StartStep);
+    AddStep(&TaskPrepareFiles::StepCopyFiles);
+    AddStep(&TaskPrepareFiles::EndStep);
+}
+
+void TaskPrepareFiles::CopyFile(const std::string& source)
+{
+    if (source.empty()) {
+        _W("No source file specified");
+        return;
+    }
+
+    std::string filename = source;
+    size_t last = source.find_last_of("\\/");
+    if (last != std::string::npos) {
+        filename = source.substr(last + 1);
+    }
+    std::string target =
+        m_installerContext.locations->getSourceDir() + '/' +
+        filename;
+    _D("source %s", source.c_str());
+    _D("target %s", target.c_str());
+
+    Try
+    {
+        DPL::FileInput input(source);
+        DPL::FileOutput output(target);
+        DPL::Copy(&input, &output);
+    }
+    Catch(DPL::FileInput::Exception::Base)
+    {
+        _E("File input error");
+        // Error while opening or closing source file
+        ReThrowMsg(Exceptions::CopyIconFailed, source);
+    }
+    Catch(DPL::FileOutput::Exception::Base)
+    {
+        _E("File output error");
+        // Error while opening or closing target file
+        ReThrowMsg(Exceptions::CopyIconFailed, target);
+    }
+    Catch(DPL::CopyFailed)
+    {
+        _E("File copy error");
+        // Error while copying
+        ReThrowMsg(Exceptions::CopyIconFailed, target);
+    }
+}
+
+void TaskPrepareFiles::StepCopyFiles()
+{
+    CopyFile(m_installerContext.locations->getWidgetSource());
+
+    size_t last = m_installerContext.locations->getWidgetSource().find_last_of(
+            "\\/");
+    std::string sourceDir = "";
+    if (last != std::string::npos) {
+        sourceDir = m_installerContext.locations->getWidgetSource().substr(
+                0,
+                last
+                + 1);
+    }
+
+    _D("Icons copy...");
+    FOREACH(it, m_installerContext.widgetConfig.configInfo.iconsList) {
+        std::ostringstream os;
+        _D("Coping: %s%ls", sourceDir.c_str(), (it->src).c_str());
+        os << sourceDir << DPL::ToUTF8String(it->src);
+        CopyFile(os.str());
+    }
+}
+
+void TaskPrepareFiles::StartStep()
+{
+    _D("--------- <TaskPrepareFiles> : START ----------");
+}
+
+void TaskPrepareFiles::EndStep()
+{
+    _D("--------- <TaskPrepareFiles> : END ----------");
+}
+} // namespace WidgetInstall
+} // namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_prepare_files.h b/src_mobile/jobs/widget_install/task_prepare_files.h
new file mode 100644 (file)
index 0000000..99458e8
--- /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       task_prepare_files.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_PREPARE_FILES_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_PREPARE_FILES_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskPrepareFiles : public DPL::TaskDecl<TaskPrepareFiles>
+{
+  private:
+    // Installation context
+    InstallerContext &m_installerContext;
+
+    void CopyFile(const std::string& source);
+
+    // Steps
+    void StepCopyFiles();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    explicit TaskPrepareFiles(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_PREPARE_FILES_H_ */
diff --git a/src_mobile/jobs/widget_install/task_prepare_reinstall.cpp b/src_mobile/jobs/widget_install/task_prepare_reinstall.cpp
new file mode 100644 (file)
index 0000000..4980e4d
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * 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_prepare_reinstall.cpp
+ * @author  Jihoon Chung(jihoon.chung@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task prepare reinstalling
+ */
+
+#include "task_prepare_reinstall.h"
+
+#include <stdio.h>
+#include <fstream>
+#include <unistd.h>
+
+#include <dpl/task.h>
+#include <dpl/string.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/job_widget_install.h>
+
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace {
+const char* const KEY_DELETE = "#delete";
+const char* const KEY_ADD = "#add";
+const char* const KEY_MODIFY = "#modify";
+std::list<std::string> keyList = {KEY_DELETE, KEY_ADD, KEY_MODIFY};
+
+void verifyFile(const std::string &filePath)
+{
+    if (access(filePath.c_str(), F_OK) != 0) {
+        ThrowMsg(Exceptions::RDSDeltaFailure, "File is missed " << filePath);
+    }
+}
+
+std::string parseSubPath(const std::string& filePath)
+{
+    std::string subPath("");
+    size_t pos = filePath.find_last_of('/') + 1;
+
+    if (pos != std::string::npos) {
+        subPath = filePath.substr(0, pos);
+    }
+    return subPath;
+}
+
+void createDir(const std::string& path)
+{
+    if (WrtUtilMakeDir(path)) {
+        _D("Create directory : %s", path.c_str());
+    } else {
+        ThrowMsg(Exceptions::RDSDeltaFailure, "Fail to create dir" << path);
+    }
+}
+} // namespace anonymous
+
+TaskPrepareReinstall::TaskPrepareReinstall(InstallerContext& context) :
+    DPL::TaskDecl<TaskPrepareReinstall>(this),
+    m_context(context)
+{
+    AddStep(&TaskPrepareReinstall::StartStep);
+    AddStep(&TaskPrepareReinstall::StepPrepare);
+    AddStep(&TaskPrepareReinstall::StepParseRDSDelta);
+    AddStep(&TaskPrepareReinstall::StepVerifyRDSDelta);
+    AddStep(&TaskPrepareReinstall::StepAddFile);
+    AddStep(&TaskPrepareReinstall::StepDeleteFile);
+    AddStep(&TaskPrepareReinstall::StepModifyFile);
+    AddStep(&TaskPrepareReinstall::EndStep);
+}
+
+void TaskPrepareReinstall::StepPrepare()
+{
+    _D("Prepare");
+    m_sourcePath = m_context.locations->getTemporaryPackageDir();
+    m_sourcePath += "/";
+
+    m_installedPath = m_context.locations->getPackageInstallationDir();
+    m_installedPath += "/";
+}
+
+void TaskPrepareReinstall::StepParseRDSDelta()
+{
+    _D("parse RDS delta");
+    std::string rdsDeltaPath = m_sourcePath;
+    rdsDeltaPath += ".rds_delta";
+    std::ifstream delta(rdsDeltaPath);
+
+    if (!delta.is_open()) {
+        ThrowMsg(Exceptions::RDSDeltaFailure, "rds_delta file is missed");
+        return;
+    }
+
+    std::string line;
+    std::string key;
+    while (std::getline(delta, line) &&!delta.eof()) {
+        FOREACH(keyIt, keyList) {
+            if (line == *keyIt) {
+                _D("find key = [%s]", line.c_str());
+                key = line;
+                break;
+            }
+        }
+        if (key == line || line.empty() || line == "\n") {
+            continue;
+        }
+        if (key == KEY_DELETE) {
+            m_deleteFileList.push_back(line);
+            _D("line = [%s]", line.c_str());
+        } else if (key == KEY_ADD) {
+            m_addFileList.push_back(line);
+            _D("line = [%s]", line.c_str());
+        } else if (key == KEY_MODIFY) {
+            m_modifyFileList.push_back(line);
+            _D("line = [%s]", line.c_str());
+        }
+    }
+}
+
+void TaskPrepareReinstall::StepVerifyRDSDelta()
+{
+    _D("verify RDS delta");
+    // Verify ADD file
+    FOREACH(file, m_addFileList) {
+        std::string addFilePath = m_sourcePath;
+        addFilePath += *file;
+        verifyFile(addFilePath);
+    }
+    // Verify DELETE file
+    FOREACH(file, m_deleteFileList) {
+        std::string deleteFilePath = m_installedPath;
+        deleteFilePath += *file;
+        verifyFile(deleteFilePath);
+    }
+    // Verify MODIFY file
+    FOREACH(file, m_modifyFileList) {
+        std::string newFilePath = m_sourcePath;
+        newFilePath += *file;
+        verifyFile(newFilePath);
+
+        std::string existingFilePath = m_installedPath;
+        existingFilePath += *file;
+        verifyFile(existingFilePath);
+    }
+    _D("Finished veify RDS Delta");
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_RDS_DELTA_CHECK,
+        "RDS delta verify finished");
+}
+
+void TaskPrepareReinstall::StepAddFile()
+{
+    _D("Add file");
+    FOREACH(file, m_addFileList) {
+        std::string newfile = m_sourcePath;
+        newfile += *file;
+        std::string destPath = m_installedPath;
+        destPath += *file;
+
+        if (WrtUtilDirExists(newfile)) {
+            // In case of a new directory
+            createDir(destPath);
+        } else {
+            // In case of a new file
+
+            // Parse directory and file separately
+            std::string subPath = parseSubPath(destPath);
+            if (subPath.empty()) {
+                ThrowMsg(Exceptions::RDSDeltaFailure,
+                         "Invalid path given" << destPath);
+            }
+
+            // Create a new directory
+            createDir(subPath);
+
+            // Add file
+            if (rename(newfile.c_str(), destPath.c_str()) != 0) {
+                ThrowMsg(Exceptions::RDSDeltaFailure,
+                        "Fail to add file " << newfile);
+            }
+            _D("Add %s to %s", newfile.c_str(), destPath.c_str());
+        }
+    }
+}
+
+void TaskPrepareReinstall::StepDeleteFile()
+{
+    _D("Delete file");
+    FOREACH(file, m_deleteFileList) {
+        std::string deleteFilePath = m_installedPath;
+        deleteFilePath += *file;
+        if (remove(deleteFilePath.c_str()) != 0) {
+            ThrowMsg(Exceptions::RDSDeltaFailure,
+                "Fail to DELETE file " << deleteFilePath);
+        }
+        _D("Delete %s", deleteFilePath.c_str());
+    }
+}
+
+void TaskPrepareReinstall::StepModifyFile()
+{
+    _D("Modify  file");
+    FOREACH(file, m_modifyFileList) {
+        std::string destPath = m_installedPath;
+        destPath += *file;
+        if (remove(destPath.c_str()) != 0) {
+            ThrowMsg(Exceptions::RDSDeltaFailure,
+                "Fail to delete existing file " << destPath);
+        }
+
+        std::string newfile = m_sourcePath;
+        newfile += *file;
+        if (rename(newfile.c_str(), destPath.c_str()) != 0) {
+            ThrowMsg(Exceptions::RDSDeltaFailure,
+                "Fail to move new file" << destPath);
+        }
+        _D("Replace %s to %s", newfile.c_str(), destPath.c_str());
+    }
+}
+
+void TaskPrepareReinstall::StartStep()
+{
+    _D("---------- <TaskPrepareReinstall> : START ----------");
+}
+
+void TaskPrepareReinstall::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_RDS_PREPARE,
+        "RDS prepare finished");
+
+    _D("---------- <TaskPrepareReinstall> : END ----------");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_prepare_reinstall.h b/src_mobile/jobs/widget_install/task_prepare_reinstall.h
new file mode 100644 (file)
index 0000000..2828f27
--- /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_prepare_reinstall.h
+ * @author  Jihoon Chung(jihoon.chung@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task prepare reinstalling
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PREPARE_REINSTALL_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PREPARE_REINSTALL_H
+
+#include <list>
+#include <dpl/task.h>
+
+#include <widget_install/widget_install_context.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskPrepareReinstall :
+    public DPL::TaskDecl<TaskPrepareReinstall>
+{
+  public:
+    TaskPrepareReinstall(InstallerContext& context);
+
+  private:
+    // install internal location
+    void StepPrepare();
+    void StepParseRDSDelta();
+    void StepVerifyRDSDelta();
+    void StepAddFile();
+    void StepDeleteFile();
+    void StepModifyFile();
+
+    void StepAbortPrepareReinstall();
+
+    void StartStep();
+    void EndStep();
+
+    InstallerContext& m_context;
+    // TODO : replace multimap
+    std::list<std::string> m_addFileList;
+    std::list<std::string> m_deleteFileList;
+    std::list<std::string> m_modifyFileList;
+    std::string m_sourcePath;
+    std::string m_installedPath;
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PREPARE_REINSTALL_H
diff --git a/src_mobile/jobs/widget_install/task_process_config.cpp b/src_mobile/jobs/widget_install/task_process_config.cpp
new file mode 100755 (executable)
index 0000000..2c92f2c
--- /dev/null
@@ -0,0 +1,681 @@
+/*
+ * 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_process_config.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task widget config
+ */
+
+#include <string>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+#include <dpl/localization/w3c_file_localization.h>
+#include <dpl/singleton_impl.h>
+#include <dpl/utils/mime_type_utils.h>
+#include <dpl/utils/wrt_global_settings.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-rw/feature_dao.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_process_config.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_parser.h>
+#include <web_provider_plugin_info.h>
+#include <web_provider_livebox_info.h>
+#include <manifest.h>
+
+#include <installer_log.h>
+
+namespace { // anonymous
+const DPL::String BR = DPL::FromUTF8String("<br>");
+const std::string WINDGET_INSTALL_NETWORK_ACCESS = "network access";
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+
+TaskProcessConfig::TaskProcessConfig(InstallerContext& installContext) :
+    DPL::TaskDecl<TaskProcessConfig>(this),
+    m_installContext(installContext)
+{
+    AddStep(&TaskProcessConfig::StartStep);
+    AddStep(&TaskProcessConfig::ReadLocaleFolders);
+    AddStep(&TaskProcessConfig::StepFillWidgetConfig);
+    AddStep(&TaskProcessConfig::ProcessLocalizedStartFiles);
+    AddStep(&TaskProcessConfig::ProcessBackgroundPageFile);
+    AddStep(&TaskProcessConfig::ProcessLocalizedIcons);
+    AddStep(&TaskProcessConfig::ProcessWidgetInstalledPath);
+    AddStep(&TaskProcessConfig::ProcessAppControlInfo);
+    AddStep(&TaskProcessConfig::ProcessSecurityModel);
+    AddStep(&TaskProcessConfig::StepVerifyFeatures);
+    AddStep(&TaskProcessConfig::StepVerifyLivebox);
+    AddStep(&TaskProcessConfig::StepCheckMinVersionInfo);
+    AddStep(&TaskProcessConfig::EndStep);
+}
+
+void TaskProcessConfig::StepFillWidgetConfig()
+{
+    if (!fillWidgetConfig(m_installContext.widgetConfig,
+                         m_installContext.widgetConfig.configInfo))
+    {
+        _E("Widget configuration is illformed");
+        ThrowMsg(Exception::ConfigParseFailed, "Widget configuration is illformed");
+    }
+}
+
+void TaskProcessConfig::ReadLocaleFolders()
+{
+    _D("Reading locale");
+    //Adding default locale
+    m_localeFolders.insert(L"");
+
+    std::string localePath =
+        m_installContext.locations->getSourceDir() + "/locales";
+
+    DIR* localeDir = opendir(localePath.c_str());
+    if (!localeDir) {
+        _D("No /locales directory in the widget package.");
+        return;
+    }
+
+    struct stat statStruct;
+    struct dirent dirent;
+    struct dirent *result;
+    int return_code;
+    errno = 0;
+    for (return_code = readdir_r(localeDir, &dirent, &result);
+            result != NULL && return_code == 0;
+            return_code = readdir_r(localeDir, &dirent, &result))
+    {
+        DPL::String dirName = DPL::FromUTF8String(dirent.d_name);
+        std::string absoluteDirName = localePath + "/";
+        absoluteDirName += dirent.d_name;
+
+        if (stat(absoluteDirName.c_str(), &statStruct) != 0) {
+            _E("stat() failed with %s", DPL::GetErrnoString().c_str());
+            continue;
+        }
+
+        if (S_ISDIR(statStruct.st_mode)) {
+            //Yes, we ignore current, parent & hidden directories
+            if (dirName[0] != L'.') {
+                _D("Adding locale directory \"%ls\"", dirName.c_str());
+                m_localeFolders.insert(dirName);
+            }
+        }
+    }
+
+    if (return_code != 0 || errno != 0) {
+        _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
+    }
+
+    if (-1 == closedir(localeDir)) {
+        _E("Failed to close dir: %s with error: %s", localePath.c_str(), DPL::GetErrnoString().c_str());
+    }
+
+    m_installContext.job->UpdateProgress(InstallerContext::INSTALL_WIDGET_CONFIG1, "Read locale folders");
+}
+
+void TaskProcessConfig::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: 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::InvalidStartFile,
+             "The Widget has no valid start file");
+}
+
+void TaskProcessConfig::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.locations->getSourceDir()) + L"/" +
+                relativePath;
+            _D("absolutePath : %ls", absolutePath.c_str());
+
+            // get property data from packaged app
+            if (WrtUtilFileExists(DPL::ToUTF8String(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.webAppType ==
+                    APP_TYPE_TIZENWEBAPP)
+                {
+                    std::string startPath = DPL::ToUTF8String(
+                            startFileData.path);
+
+                    if (strstr(startPath.c_str(),
+                               "http") == startPath.c_str())
+                    {
+                        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 TaskProcessConfig::ProcessBackgroundPageFile()
+{
+    if (!!m_installContext.widgetConfig.configInfo.backgroundPage) {
+        // check whether file exists
+        DPL::String backgroundPagePath = DPL::FromUTF8String(
+                m_installContext.locations->getSourceDir()) + L"/" +
+            *m_installContext.widgetConfig.configInfo.backgroundPage;
+        //if no then cancel installation
+        if (!WrtUtilFileExists(DPL::ToUTF8String(backgroundPagePath))) {
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid,
+                     L"Given background page file not found in archive");
+        }
+    }
+}
+
+void TaskProcessConfig::ProcessLocalizedIcons()
+{
+    using namespace WrtDB;
+    FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList)
+    {
+        ProcessIcon(*i);
+    }
+    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"));
+}
+
+void TaskProcessConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon)
+{
+    _D("enter");
+    bool isAnyIconValid = 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.locations->getSourceDir()) + L"/" +
+            relativePath;
+
+        if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) {
+            DPL::String type = MimeTypeUtils::identifyFileMimeType(absolutePath);
+
+            if (MimeTypeUtils::isMimeTypeSupportedForIcon(type)) {
+                isAnyIconValid = true;
+                localesAvailableForIcon.insert(*i);
+                _D("Icon absolutePath: %ls, assigned locale: %ls, type: %ls",
+                    absolutePath.c_str(), (*i).c_str(), type.c_str());
+            }
+        }
+    }
+
+    if (isAnyIconValid) {
+        WidgetRegisterInfo::LocalizedIcon localizedIcon(icon,
+                                                        localesAvailableForIcon);
+        m_installContext.widgetConfig.localizationData.icons.push_back(
+            localizedIcon);
+    }
+}
+
+void TaskProcessConfig::ProcessWidgetInstalledPath()
+{
+    _D("ProcessWidgetInstalledPath");
+    m_installContext.widgetConfig.widgetInstalledPath =
+        DPL::FromUTF8String(
+            m_installContext.locations->getPackageInstallationDir());
+}
+
+void TaskProcessConfig::ProcessAppControlInfo()
+{
+    _D("ProcessAppControlInfo");
+    using namespace WrtDB;
+
+    // In case of dispostion is inline, set the seperate execute
+    int index = 1;
+    // 0 index is reserved by default execute
+    FOREACH(it, m_installContext.widgetConfig.configInfo.appControlList) {
+        if (it->m_disposition ==
+            ConfigParserData::AppControlInfo::Disposition::INLINE)
+        {
+            it->m_index = index++;
+        } else {
+            it->m_index = 0;
+        }
+    }
+}
+
+void TaskProcessConfig::ProcessSecurityModel()
+{
+    // 0104.  If the "required_version" specified in the Web Application's
+    // configuration is 2.2 or higher and if the Web Application's
+    // configuration is "CSP-compatible configuration", then the WRT MUST be
+    // set to "CSP-based security mode". Otherwise, the WRT MUST be set to
+    // "WARP-based security mode".
+    // 0105.  A Web Application configuration is "CSP-compatible configuration"
+    // if the configuration includes one or more of
+    // <tizen:content-security-policy> /
+    // <tizen:content-security-policy-report-only> /
+    // <tizen:allow-navigation> elements.
+
+    bool isSecurityModelV1 = false;
+    bool isSecurityModelV2 = false;
+    WrtDB::ConfigParserData &data = m_installContext.widgetConfig.configInfo;
+
+    if (!data.cspPolicy.IsNull() ||
+        !data.cspPolicyReportOnly.IsNull() ||
+        !data.allowNavigationInfoList.empty())
+    {
+        data.accessInfoSet.clear();
+    }
+
+    // WARP is V1
+    if (!data.accessInfoSet.empty()) {
+        isSecurityModelV1 = true;
+    }
+
+    // CSP & allow-navigation is V2
+    if (!data.cspPolicy.IsNull() ||
+        !data.cspPolicyReportOnly.IsNull() ||
+        !data.allowNavigationInfoList.empty())
+    {
+        isSecurityModelV2 = true;
+    }
+
+    if (isSecurityModelV1 && isSecurityModelV2) {
+        _E("Security model is conflict");
+        ThrowMsg(Exceptions::NotAllowed, "Security model is conflict");
+    } else if (isSecurityModelV1) {
+        data.securityModelVersion =
+            WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
+    } else if (isSecurityModelV2) {
+        data.securityModelVersion =
+            WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V2;
+    } else {
+        data.securityModelVersion =
+            WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
+    }
+
+    m_installContext.job->UpdateProgress(
+        InstallerContext::INSTALL_WIDGET_CONFIG2,
+        "Finished process security model");
+}
+
+void TaskProcessConfig::StepCheckMinVersionInfo()
+{
+    if (!isMinVersionCompatible(
+            m_installContext.widgetConfig.webAppType.appType,
+            m_installContext.widgetConfig.minVersion))
+    {
+        _E("Platform version lower than required -> cancelling installation");
+        ThrowMsg(Exceptions::NotAllowed,
+                 "Platform version does not meet requirements");
+    }
+
+    m_installContext.job->UpdateProgress(
+        InstallerContext::INSTALL_WIDGET_CONFIG2,
+        "Check MinVersion Finished");
+}
+
+void TaskProcessConfig::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.webAppType.appType,
+                              it->name))
+        {
+            _D("This application type not allowed to use this feature");
+            ThrowMsg(
+                Exceptions::WidgetConfigFileInvalid,
+                "This app type [" <<
+                m_installContext.widgetConfig.webAppType.getApptypeToString()
+                                  <<
+                "] cannot be allowed to use [" <<
+                DPL::ToUTF8String(it->name) + "] feature");
+        } else {
+            newList.insert(*it);
+            featureInfo += DPL::ToUTF8String(it->name);
+            featureInfo += DPL::ToUTF8String(BR);
+        }
+    }
+    if (!data.accessInfoSet.empty()) {
+        featureInfo += WINDGET_INSTALL_NETWORK_ACCESS;
+        featureInfo += DPL::ToUTF8String(BR);
+    }
+    data.featuresList = newList;
+
+    m_installContext.job->UpdateProgress(
+        InstallerContext::INSTALL_WIDGET_CONFIG2,
+        "Widget Config step2 Finished");
+}
+
+void TaskProcessConfig::StepVerifyLivebox()
+{
+    using namespace WrtDB;
+    ConfigParserData &data = m_installContext.widgetConfig.configInfo;
+    ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
+
+    if (liveBoxList.size() <= 0) {
+        return;
+    }
+
+    FOREACH (it, liveBoxList) {
+        std::string boxType;
+
+        if ((**it).m_liveboxId.find(m_installContext.widgetConfig.tzAppid) != 0) {
+            _E("Invalid app-widget id (doesn't begin with application id)");
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Invalid app-widget id (doesn't begin with application id)");
+        }
+
+        if ((**it).m_type.empty()) {
+            boxType = web_provider_livebox_get_default_type();
+        } else {
+            boxType = DPL::ToUTF8String((**it).m_type);
+        }
+
+        _D("livebox type: %s", boxType.c_str());
+
+        ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+            (**it).m_boxInfo.m_boxSize;
+        char** boxSize = static_cast<char**>(
+            malloc(sizeof(char*)* boxSizeList.size()));
+
+        int boxSizeCnt = 0;
+        FOREACH (m, boxSizeList) {
+            boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).m_size).c_str());
+        }
+
+        bool chkSize = web_provider_plugin_check_supported_size(
+            boxType.c_str(), boxSize, boxSizeCnt);
+
+        for(int i = 0; i < boxSizeCnt; i++) {
+            free(boxSize[i]);
+        }
+        free(boxSize);
+
+        if(!chkSize) {
+            _E("Invalid boxSize");
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Invalid boxSize");
+        }
+    }
+}
+
+bool TaskProcessConfig::isFeatureAllowed(WrtDB::AppType appType,
+                                        DPL::String featureName)
+{
+    using namespace WrtDB;
+    _D("AppType = [%s]", WidgetType(appType).getApptypeToString().c_str());
+    _D("FetureName = [%ls]", featureName.c_str());
+
+    AppType featureType = APP_TYPE_UNKNOWN;
+    std::string featureStr = DPL::ToUTF8String(featureName);
+    const char* feature = featureStr.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::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;
+}
+
+bool TaskProcessConfig::parseVersionString(const std::string &version,
+                                          long &majorVersion,
+                                          long &minorVersion,
+                                          long &microVersion) const
+{
+    std::istringstream inputString(version);
+    inputString >> majorVersion;
+    if (inputString.bad() || inputString.fail()) {
+        _W("Invalid minVersion format.");
+        return false;
+    }
+    inputString.get(); // skip period
+    inputString >> minorVersion;
+    if (inputString.bad() || inputString.fail()) {
+        _W("Invalid minVersion format");
+        return false;
+    } else {
+        inputString.get(); // skip period
+        if (inputString.bad() || inputString.fail()) {
+            inputString >> microVersion;
+        }
+    }
+    return true;
+}
+
+bool TaskProcessConfig::isMinVersionCompatible(
+    WrtDB::AppType appType,
+    const DPL::OptionalString &
+    widgetVersion) const
+{
+    if (widgetVersion.IsNull() || (*widgetVersion).empty()) {
+        if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP) {
+            return false;
+        } else {
+            _W("minVersion attribute is empty. WRT assumes platform "
+               "supports this widget.");
+            return true;
+        }
+    }
+
+    //Parse widget version
+    long majorWidget = 0, minorWidget = 0, microWidget = 0;
+    if (!parseVersionString(DPL::ToUTF8String(*widgetVersion), majorWidget,
+                            minorWidget, microWidget))
+    {
+        _W("Invalid format of widget version string.");
+        return false;
+    }
+
+    //Parse supported version
+    long majorSupported = 0, minorSupported = 0, microSupported = 0;
+    std::string version;
+    if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP) {
+        version = WrtDB::GlobalConfig::GetTizenVersion();
+    } else {
+        _W("Invaild AppType");
+        return false;
+    }
+
+    if (!parseVersionString(version,
+                            majorSupported, minorSupported, microSupported))
+    {
+        _W("Invalid format of platform version string.");
+        return true;
+    }
+
+    if (majorWidget > majorSupported ||
+        (majorWidget == majorSupported && minorWidget > minorSupported) ||
+        (majorWidget == majorSupported && minorWidget == minorSupported
+         && microWidget > microSupported))
+    {
+        _D("Platform doesn't support this widget.");
+        return false;
+    }
+    return true;
+}
+
+bool TaskProcessConfig::isTizenWebApp() const
+{
+    if (m_installContext.widgetConfig.webAppType.appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
+    {
+        return true;
+    }
+    return false;
+}
+
+bool TaskProcessConfig::fillWidgetConfig(
+    WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
+    WrtDB::ConfigParserData& configInfo)
+{
+    pWidgetConfigInfo.guid = configInfo.widget_id;
+
+    if (!!configInfo.version) {
+        if (!pWidgetConfigInfo.version) {
+            pWidgetConfigInfo.version = configInfo.version;
+        } else {
+            if (pWidgetConfigInfo.version != configInfo.version) {
+                _E("Invalid archive");
+                return false;
+            }
+        }
+    }
+    if (!!configInfo.minVersionRequired) {
+        pWidgetConfigInfo.minVersion = configInfo.minVersionRequired;
+    } else if (!!configInfo.tizenMinVersionRequired) {
+        pWidgetConfigInfo.minVersion = configInfo.tizenMinVersionRequired;
+    }
+    return true;
+}
+
+void TaskProcessConfig::StartStep()
+{
+    _D("--------- <TaskProcessConfig> : START ----------");
+}
+
+void TaskProcessConfig::EndStep()
+{
+    _D("--------- <TaskProcessConfig> : END ----------");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_process_config.h b/src_mobile/jobs/widget_install/task_process_config.h
new file mode 100755 (executable)
index 0000000..8d844d6
--- /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.
+ */
+/*
+ * @file    task_process_config.h
+ * @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_PROCESS_CONFIG_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PROCESS_CONFIG_H
+
+#include <set>
+#include <list>
+
+#include <dpl/task.h>
+#include <dpl/task_list.h>
+#include <dpl/string.h>
+#include <dpl/optional.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <wrt_common_types.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+class TaskProcessConfig :
+    public DPL::TaskDecl<TaskProcessConfig>
+{
+  private:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ConfigParseFailed)
+    };
+
+    typedef std::list<std::pair<DPL::String, DPL::String> > StringPairList;
+
+    InstallerContext& m_installContext;
+    WrtDB::LocaleSet m_localeFolders;
+    std::set<DPL::String> m_processedIconSet;
+
+    void StepFillWidgetConfig();
+    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 ProcessBackgroundPageFile();
+    void ProcessLocalizedIcons();
+    void ProcessIcon(const WrtDB::ConfigParserData::Icon& icon);
+    void ProcessWidgetInstalledPath();
+    void ProcessAppControlInfo();
+    void ProcessSecurityModel();
+    void StepVerifyFeatures();
+    void StepVerifyLivebox();
+    void StepCheckMinVersionInfo();
+
+    template <typename Ex, const char* Msg>
+    void StepCancelInstallation();
+
+    void StartStep();
+    void EndStep();
+
+    DPL::String createAuthorWidgetInfo() const;
+    bool isFeatureAllowed(
+        WrtDB::AppType appType, DPL::String featureName);
+    bool isMinVersionCompatible(
+        WrtDB::AppType appType,
+        const DPL::OptionalString &widgetVersion) const;
+    /**
+     * @brief Parses version string in format "major.minor.micro anything"
+     * Returns false if format is invalid
+     */
+    bool isTizenWebApp() const;
+    bool parseVersionString(const std::string &version, long &majorVersion,
+                            long &minorVersion, long &microVersion) const;
+
+    bool fillWidgetConfig(WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
+                          WrtDB::ConfigParserData& configInfo);
+
+  public:
+    TaskProcessConfig(InstallerContext& installTaskContext);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PROCESS_CONFIG_H
diff --git a/src_mobile/jobs/widget_install/task_recovery.cpp b/src_mobile/jobs/widget_install/task_recovery.cpp
new file mode 100644 (file)
index 0000000..cf9d952
--- /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    task_recovery.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task recovery
+ */
+#include "task_recovery.h"
+
+#include <pwd.h>
+#include <grp.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string>
+#include <ail.h>
+
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/utils/wrt_utility.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskRecovery::TaskRecovery(InstallerContext& context) :
+    DPL::TaskDecl<TaskRecovery>(this),
+    m_context(context)
+{
+    AddStep(&TaskRecovery::StartStep);
+    AddStep(&TaskRecovery::StepCreateCheckFile);
+    AddStep(&TaskRecovery::EndStep);
+}
+
+void TaskRecovery::StartStep()
+{
+    _D("---------- <TaskRecovery> : START ----------");
+}
+
+void TaskRecovery::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_CHECK_FILE,
+        "Create information file for recovery");
+
+    _D("---------- <TaskRecovery> : END ----------");
+}
+
+void TaskRecovery::StepCreateCheckFile()
+{
+    _D("Step: create information file for recovery");
+
+    size_t pos = m_context.locations->getWidgetSource().rfind("/");
+    std::ostringstream infoPath;
+    infoPath << GlobalConfig::GetTempInstallInfoPath();
+    infoPath << "/";
+    infoPath << m_context.locations->getWidgetSource().substr(pos + 1);
+
+    FILE *temp = fopen(infoPath.str().c_str(), "w+");
+    if (temp != NULL) {
+        fputs(m_context.locations->getWidgetSource().c_str(), temp);
+        int ret = fsync(temp->_fileno);
+        fclose(temp);
+        if (-1 == ret) {
+            ThrowMsg(Exceptions::FileOperationFailed, "Fail to fsync for recovery.");
+        }
+
+        m_context.installInfo = infoPath.str();
+
+        _D("Create file : %s", m_context.installInfo.c_str());
+    } else {
+        ThrowMsg(Exceptions::FileOperationFailed, "Fail to create file for recovery.");
+    }
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_recovery.h b/src_mobile/jobs/widget_install/task_recovery.h
new file mode 100644 (file)
index 0000000..22503a3
--- /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       task_recovery.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_RECOVERY_FILES_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_RECOVERY_FILES_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskRecovery : public DPL::TaskDecl<TaskRecovery>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+
+    void StepCreateCheckFile();
+    void StartStep();
+    void EndStep();
+
+  public:
+    explicit TaskRecovery(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_RECOVERY_FILES_H_ */
diff --git a/src_mobile/jobs/widget_install/task_remove_backup.cpp b/src_mobile/jobs/widget_install/task_remove_backup.cpp
new file mode 100644 (file)
index 0000000..10caf9e
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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_backup.cpp
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task backup files remove
+ */
+#include <widget_install/task_remove_backup.h>
+
+#include <sys/stat.h>
+#include <string>
+#include <sstream>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/foreach.h>
+#include <dpl/assert.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskRemoveBackupFiles::TaskRemoveBackupFiles(InstallerContext& context) :
+    DPL::TaskDecl<TaskRemoveBackupFiles>(this),
+    m_context(context)
+{
+    AddStep(&TaskRemoveBackupFiles::StartStep);
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
+    {
+        AddStep(&TaskRemoveBackupFiles::StepRemoveBackupFiles);
+    }
+    AddStep(&TaskRemoveBackupFiles::StepDeleteBackupDB);
+    AddStep(&TaskRemoveBackupFiles::StepDeleteBackupWidgetInterfaceDB);
+    AddStep(&TaskRemoveBackupFiles::EndStep);
+}
+
+void TaskRemoveBackupFiles::StepRemoveBackupFiles()
+{
+    std::ostringstream backupDir;
+    backupDir << m_context.locations->getBackupDir();
+
+    if (WrtUtilRemove(backupDir.str())) {
+        _D("Success to remove backup files : %s", backupDir.str().c_str());
+    } else {
+        _E("Failed to remove backup directory : %s", backupDir.str().c_str());
+        ThrowMsg(Exceptions::RemoveBackupFailed,
+                 "Error occurs during removing existing folder");
+    }
+
+    std::string tmp = m_context.locations->getTemporaryPackageDir();
+    if (WrtUtilRemove(tmp)) {
+        _D("Success to remove temp directory : %s", tmp.c_str());
+    } else {
+        _E("Failed to remove temp directory : %s", tmp.c_str());
+    }
+}
+
+void TaskRemoveBackupFiles::StepDeleteBackupDB()
+{
+    _D("StepDeleteBackupDB");
+    std::string oldAppid =
+        DPL::ToUTF8String(m_context.widgetConfig.tzAppid) + ".backup";
+
+    Try
+    {
+        WidgetDAO::unregisterWidget(DPL::FromUTF8String(oldAppid));
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+    {
+        _E("Fail to delete old version db information");
+    }
+}
+
+void TaskRemoveBackupFiles::StepDeleteBackupWidgetInterfaceDB()
+{
+    _D("StepDeleteBackupWidgetInterfaceDB");
+    using namespace WidgetInterfaceDB;
+    using namespace WrtDB;
+
+    DbWidgetHandle handle =
+        WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+    std::string backupDbPath = WidgetInterfaceDAO::databaseFileName(handle);
+    backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
+
+    // remove backup database
+    if (remove(backupDbPath.c_str()) != 0) {
+        _W("Fail to remove");
+    }
+}
+
+void TaskRemoveBackupFiles::StartStep()
+{
+    _D("--------- <TaskRemoveBackupFiles> : START ----------");
+}
+
+void TaskRemoveBackupFiles::EndStep()
+{
+    _D("--------- <TaskRemoveBackupFiles> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_remove_backup.h b/src_mobile/jobs/widget_install/task_remove_backup.h
new file mode 100644 (file)
index 0000000..1dcdf5b
--- /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_remove_backup.h
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task backup files remove
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_REMOVE_BACKUP_FILES_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_REMOVE_BACKUP_FILES_H
+
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskRemoveBackupFiles :
+    public DPL::TaskDecl<TaskRemoveBackupFiles>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StepRemoveBackupFiles();
+    void StepDeleteBackupDB();
+    void StepDeleteBackupWidgetInterfaceDB();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskRemoveBackupFiles(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_REMOVE_BACKUP_FILES_H
diff --git a/src_mobile/jobs/widget_install/task_smack.cpp b/src_mobile/jobs/widget_install/task_smack.cpp
new file mode 100644 (file)
index 0000000..0114c4e
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * 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/wrt-dao-ro/common_dao_types.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/utils/bash_utils.h>
+#include <vcore/Certificate.h>
+#include <vcore/CryptoHash.h>
+#ifdef WRT_SMACK_ENABLED
+#include <privilege-control.h>
+#include <sys/smack.h>
+#endif
+#include <sstream>
+#include <installer_log.h>
+#include <privilege-control.h>
+
+using namespace WrtDB;
+using namespace ValidationCore;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+void freeList(const char** list) {
+    for (int i = 0; list[i] != NULL; i++)
+    {
+        delete(list[i]);
+    }
+    delete[] list;
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskSmack::TaskSmack(InstallerContext& context) :
+    DPL::TaskDecl<TaskSmack>(this),
+    m_context(context),
+    m_pkgId(NULL)
+{
+    AddStep(&TaskSmack::StartStep);
+    AddStep(&TaskSmack::StepSetInstall);
+    AddStep(&TaskSmack::StepSmackFolderLabeling);
+    AddStep(&TaskSmack::StepSmackPrivilege);
+    AddStep(&TaskSmack::StepAddLabelNPRuntime);
+    AddStep(&TaskSmack::EndStep);
+
+    AddAbortStep(&TaskSmack::StepAbortSmack);
+}
+
+void TaskSmack::StepSetInstall()
+{
+    _D("----------------> SMACK: StepStartSetSmack()");
+#ifdef WRT_SMACK_ENABLED
+    std::string pkg = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+    m_pkgId = (char*)calloc(1, pkg.length() + 1);
+    snprintf(m_pkgId, pkg.length() + 1, "%s", pkg.c_str());
+
+    if (m_context.widgetConfig.packagingType !=
+            WrtDB::PkgType::PKG_TYPE_HYBRID_WEB_APP)
+    {
+            if (PC_OPERATION_SUCCESS != perm_app_install(m_pkgId)) {
+            free(m_pkgId);
+            ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+                    "failure in creating smack rules file.");
+        }
+    }
+#endif
+}
+
+void TaskSmack::StepSmackFolderLabeling()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
+#ifdef WRT_SMACK_ENABLED
+    /* /opt/usr/apps/[pkgid] directory's label is "_" */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
+                m_context.locations->getPackageInstallationDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        _W("Add label to %s", m_context.locations->getPackageInstallationDir().c_str());
+    }
+
+    /* for prelaod */
+    if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD &&
+            m_context.mode.extension != InstallMode::ExtensionType::DIR)
+    {
+        if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
+                    m_context.locations->getUserDataRootDir().c_str(),
+                    APP_PATH_ANY_LABEL, "_")) {
+        }
+    }
+
+    /* res directory */
+    std::string resDir = m_context.locations->getPackageInstallationDir() +
+        "/res";
+
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId, resDir.c_str(),
+                APP_PATH_PRIVATE)) {
+        _W("Add label to %s", resDir.c_str());
+    }
+
+    /* data directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
+                m_context.locations->getPrivateStorageDir().c_str(),
+                APP_PATH_PRIVATE)) {
+        _W("Add label to %s", m_context.locations->getPrivateStorageDir().c_str());
+    }
+
+    /* tmp directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
+                m_context.locations->getPrivateTempStorageDir().c_str(),
+                APP_PATH_PRIVATE))
+    {
+        _W("Add label to %s", m_context.locations->getPrivateTempStorageDir().c_str());
+    }
+
+    /* bin directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId,
+                m_context.locations->getBinaryDir().c_str(),
+                APP_PATH_PRIVATE)) {
+        _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
+    }
+
+    if(!setLabelForSharedDir(m_pkgId)) {
+        _W("Add label to shared directory");
+    }
+
+    free(m_pkgId);
+
+    /* TODO : set label at wrt-client */
+#endif
+}
+
+void TaskSmack::StepSmackPrivilege()
+{
+    _D("----------------> SMACK:\
+        Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
+#ifdef WRT_SMACK_ENABLED
+    /* TODO :
+    std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+    */
+    std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+    char* appId = NULL;
+    appId = (char*)calloc(1, id.length() + 1);
+    snprintf(appId, id.length() + 1, "%s", id.c_str());
+
+    WrtDB::ConfigParserData::PrivilegeList privileges =
+        m_context.widgetConfig.configInfo.privilegeList;
+
+    char** perm_list = new char*[privileges.size() + 1];
+    int index = 0;
+    FOREACH(it, privileges) {
+        _D("Permission : %ls", it->name.c_str());
+        int length = DPL::ToUTF8String(it->name).length();
+        char *priv = new char[length + 1];
+        snprintf(priv, length + 1, "%s",
+                 DPL::ToUTF8String(it->name).c_str());
+        perm_list[index++] = priv;
+    }
+    perm_list[index] = NULL;
+
+    if (PC_OPERATION_SUCCESS != perm_app_enable_permissions(appId, APP_TYPE_WGT,
+                const_cast<const char **>(perm_list), true)) {
+        _W("failure in contructing smack rules based on perm_list");
+    }
+
+    free(appId);
+    index = 0;
+    while (NULL != perm_list[index]) {
+        delete [] perm_list[index++];
+    }
+    delete [] perm_list;
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_SMACK_ENABLE,
+        "Widget SMACK Enabled");
+#endif
+}
+
+void TaskSmack::StepAddLabelNPRuntime()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepAddLabelNPRuntime()");
+    if (0 == access(m_context.locations->getNPPluginsDir().c_str(), F_OK)) {
+        if (PC_OPERATION_SUCCESS !=
+                perm_app_setup_path(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid).c_str(),
+                    m_context.locations->getNPPluginsExecFile().c_str(),
+                    PERM_APP_PATH_NPRUNTIME)) {
+            _E("failed to set smack execute label to %s",
+                    m_context.locations->getNPPluginsExecFile().c_str());
+        }
+    }
+}
+
+void TaskSmack::StepRevokeForUpdate()
+{
+    _D("----------------> SMACK:\
+        Jobs::WidgetInstall::TaskSmack::StepRevokePrivilegeForUpdate()");
+#ifdef WRT_SMACK_ENABLED
+    if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
+        _W("failure in revoking smack permissions");
+    }
+#endif
+}
+
+void TaskSmack::StepAbortSmack()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
+#ifdef WRT_SMACK_ENABLED
+
+    if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId)) {
+        _W("failure in revoking smack permissions");
+    }
+
+    if (PC_OPERATION_SUCCESS != perm_app_uninstall(m_pkgId)) {
+        _W("failure in removing smack rules file");
+    }
+    free(m_pkgId);
+#endif
+}
+
+bool TaskSmack::setLabelForSharedDir(const char* pkgId)
+{
+    /* /shared directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                m_context.locations->getSharedRootDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        _W("Add label to %s", m_context.locations->getUserDataRootDir().c_str());
+    }
+
+    /* /shared/res directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                m_context.locations->getSharedResourceDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        _W("Add label to %s", m_context.locations->getSharedResourceDir().c_str());
+    }
+
+    /* /shared/trusted directory */
+    CertificatePtr rootCert = m_context.widgetSecurity.getAuthorCertificatePtr();
+    if (rootCert.Get() != NULL) {
+        ValidationCore::Crypto::Hash::SHA1 sha1;
+        sha1.Append(rootCert->getDER());
+        sha1.Finish();
+        std::string sha1String = sha1.ToBase64String();
+        size_t iPos = sha1String.find("/");
+        while(iPos < std::string::npos) {
+            sha1String.replace(iPos, 1, "#");
+            iPos = sha1String.find("/");
+        }
+
+        _D("sha1 label string : %s", sha1String.c_str());
+
+        if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                    m_context.locations->getSharedTrustedDir().c_str(),
+                    APP_PATH_GROUP_RW, sha1String.c_str())) {
+            _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
+        }
+    }
+
+    /* /shared/data directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                m_context.locations->getSharedDataDir().c_str(),
+                APP_PATH_PUBLIC_RO)) {
+        _W("Add label to %s", m_context.locations->getSharedDataDir().c_str());
+    }
+
+    return true;
+}
+
+void TaskSmack::StartStep()
+{
+    _D("--------- <TaskSmack> : START ----------");
+    if (PC_OPERATION_SUCCESS != perm_begin()) {
+        _E("Failed to smack transaction begin.");
+        ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction begin");
+    }
+}
+
+void TaskSmack::EndStep()
+{
+    _D("--------- <TaskSmack> : END ----------");
+    if (PC_OPERATION_SUCCESS != perm_end()) {
+        _E("Failed to smack transaction end.");
+        ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction end");
+    }
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_smack.h b/src_mobile/jobs/widget_install/task_smack.h
new file mode 100644 (file)
index 0000000..d1895c2
--- /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    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>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskSmack :
+    public DPL::TaskDecl<TaskSmack>
+{
+  private:
+    InstallerContext& m_context;
+    char* m_pkgId;
+
+    void StepSetInstall();
+    void StepSmackFolderLabeling();
+    void StepSmackPrivilege();
+    void StepAddLabelNPRuntime();
+    void StepRevokeForUpdate();
+    void StepAbortSmack();
+
+    bool setLabelForSharedDir(const char* pkgId);
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskSmack(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_SMACK_H */
diff --git a/src_mobile/jobs/widget_install/task_update_files.cpp b/src_mobile/jobs/widget_install/task_update_files.cpp
new file mode 100644 (file)
index 0000000..ef27d30
--- /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.
+ */
+/*
+ * @file    task_update_files.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task update files
+ */
+
+#include <unistd.h>
+#include <utility>
+#include <vector>
+#include <string>
+#include <algorithm>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+
+#include <widget_install/task_update_files.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/directory_api.h>
+#include <widget_install_to_external.h>
+#include <pkgmgr/pkgmgr_parser.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+inline const char* GetWidgetBackupDirPath()
+{
+    return "backup";
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) :
+    DPL::TaskDecl<TaskUpdateFiles>(this),
+    m_context(context)
+{
+    AddStep(&TaskUpdateFiles::StartStep);
+    AddStep(&TaskUpdateFiles::StepBackupDirectory);
+    AddStep(&TaskUpdateFiles::EndStep);
+
+    AddAbortStep(&TaskUpdateFiles::StepAbortBackupDirectory);
+}
+
+void TaskUpdateFiles::StepBackupDirectory()
+{
+    _D("StepCreateBackupFolder");
+
+    Try {
+        std::string pkgid =
+            DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+        if (APP2EXT_SD_CARD == app2ext_get_app_location(pkgid.c_str())) {
+            _D("Installed external directory");
+            WidgetInstallToExtSingleton::Instance().initialize(pkgid);
+            WidgetInstallToExtSingleton::Instance().disable();
+        }
+    } Catch(WidgetInstallToExt::Exception::ErrorInstallToExt) {
+        _E("Failed disable app2sd");
+        ReThrowMsg(Exceptions::BackupFailed, "Error occurs during disable app2sd");
+    }
+
+    std::string backPath = m_context.locations->getBackupDir();
+    _D("Backup resource directory path : %s", backPath.c_str());
+    std::string pkgPath = m_context.locations->getPackageInstallationDir();
+
+    if (0 == access(backPath.c_str(), F_OK)) {
+        if (!WrtUtilRemove(backPath)) {
+            ThrowMsg(Exceptions::RemovingFolderFailure,
+                    "Error occurs during removing backup resource directory");
+        }
+    }
+    _D("copy : %s to %s", pkgPath.c_str(), backPath.c_str());
+    if ((rename(pkgPath.c_str(), backPath.c_str())) != 0) {
+        _E("Failed to rename %s to %s", pkgPath.c_str(), backPath.c_str());
+        ThrowMsg(Exceptions::BackupFailed,
+                "Error occurs during rename file");
+    }
+
+    WrtUtilMakeDir(pkgPath);
+}
+
+void TaskUpdateFiles::StepAbortBackupDirectory()
+{
+    _D("StepAbortCopyFiles");
+
+    std::string backPath = m_context.locations->getBackupDir();
+    std::string pkgPath = m_context.locations->getPackageInstallationDir();
+
+    _D("Backup Folder %s to %s", backPath.c_str(), pkgPath.c_str());
+
+    if (!WrtUtilRemove(pkgPath)) {
+        _E("Failed to remove %s", pkgPath.c_str());
+    }
+
+    if (rename(backPath.c_str(), pkgPath.c_str()) != 0) {
+        _E("Failed to rename %s to %s", backPath.c_str(), pkgPath.c_str());
+    }
+}
+
+void TaskUpdateFiles::StartStep()
+{
+    _D("--------- <TaskUpdateFiles> : START ----------");
+}
+
+void TaskUpdateFiles::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_CREATE_BACKUP_DIR,
+        "Backup directory created for update");
+
+    _D("--------- <TaskUpdateFiles> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_update_files.h b/src_mobile/jobs/widget_install/task_update_files.h
new file mode 100644 (file)
index 0000000..1d02e0e
--- /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    task_update_files.h
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task update files
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UPDATE_FILES_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UPDATE_FILES_H
+
+#include <set>
+#include <dpl/task.h>
+#include <dpl/string.h>
+
+class InstallerContext;
+
+namespace {
+typedef std::set<std::string> ExistFileList;
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskUpdateFiles :
+    public DPL::TaskDecl<TaskUpdateFiles>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StepBackupDirectory();
+
+    void StepAbortBackupDirectory();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskUpdateFiles(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UPDATE_FILES_H */
diff --git a/src_mobile/jobs/widget_install/task_user_data_manipulation.cpp b/src_mobile/jobs/widget_install/task_user_data_manipulation.cpp
new file mode 100644 (file)
index 0000000..808529e
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * 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_user_data_manipulation.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task user data folder 
+ */
+#include <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <widget_install/task_user_data_manipulation.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/directory_api.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/assert.h>
+#include <dpl/errno_string.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <string>
+#include <installer_log.h>
+
+#define WEBAPP_DEFAULT_UID  5000
+#define WEBAPP_DEFAULT_GID  5000
+
+namespace {
+const mode_t PRIVATE_STORAGE_MODE = 0700;
+const mode_t SHARED_STORAGE_MODE = 0755;
+}
+
+using namespace WrtDB;
+
+namespace {
+void changeOwnerForDirectory(std::string storagePath, mode_t mode) {
+    if (euidaccess(storagePath.c_str(), F_OK) != 0) {
+        if (!WrtUtilMakeDir(storagePath, mode)) {
+            _E("Failed to create directory : %s", storagePath.c_str());
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "Failed to create directory : " << storagePath);
+        }
+        // '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.c_str(),
+                  WEBAPP_DEFAULT_UID,
+                  WEBAPP_DEFAULT_GID) != 0)
+        {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "Chown to invaild user");
+        }
+    } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) {
+        _D("%s already exists.", storagePath.c_str());
+        // Even if private directory already is created, private dircetory
+        // should change owner (recursively).
+        if (chown(storagePath.c_str(),
+                  WEBAPP_DEFAULT_UID,
+                  WEBAPP_DEFAULT_GID) != 0)
+        {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "Chown to invaild user");
+        }
+        if (chmod(storagePath.c_str(), mode) != 0) {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "chmod to 0700");
+        }
+    } else {
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                 "No access to private storage.");
+    }
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskUserDataManipulation::TaskUserDataManipulation(InstallerContext& context) :
+    DPL::TaskDecl<TaskUserDataManipulation>(this),
+    m_context(context)
+{
+    AddStep(&TaskUserDataManipulation::StartStep);
+    AddStep(&TaskUserDataManipulation::StepCreatePrivateStorageDir);
+    AddStep(&TaskUserDataManipulation::StepCreateSharedFolder);
+    AddStep(&TaskUserDataManipulation::StepLinkForPreload);
+    AddStep(&TaskUserDataManipulation::EndStep);
+}
+
+void TaskUserDataManipulation::StepCreatePrivateStorageDir()
+{
+    std::string storagePath = m_context.locations->getPrivateStorageDir();
+    _D("Create private storage directory : %s", m_context.locations->getPrivateStorageDir().c_str());
+
+    changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE);
+
+    if (m_context.isUpdateMode) { //update
+        std::string backData = m_context.locations->getBackupPrivateDir();
+        _D("copy private storage %s to %s", backData.c_str(), storagePath.c_str());
+        if (!DirectoryApi::DirectoryCopy(backData, storagePath)) {
+            _E("Failed to rename %s to %s", backData.c_str(), storagePath.c_str());
+            ThrowMsg(Exceptions::BackupFailed,
+                    "Error occurs copy private strage files");
+        }
+    }
+
+    std::string tempStoragePath = m_context.locations->getPrivateTempStorageDir();
+    _D("Create temp private storage directory : %s", tempStoragePath.c_str());
+    changeOwnerForDirectory(tempStoragePath, PRIVATE_STORAGE_MODE);
+}
+
+void TaskUserDataManipulation::StepLinkForPreload()
+{
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        std::string optRes = m_context.locations->getUserDataRootDir() +
+            WrtDB::GlobalConfig::GetWidgetResPath();
+        std::string usrRes = m_context.locations->getPackageInstallationDir() +
+            WrtDB::GlobalConfig::GetWidgetResPath();
+
+        if (0 != access(optRes.c_str(), F_OK)) {
+            _D("Make symbolic name for preload app %s to %s", usrRes.c_str(), optRes.c_str());
+
+            if (symlink(usrRes.c_str(), optRes.c_str()) != 0)
+            {
+                int error = errno;
+                if (error)
+                    _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str());
+                ThrowMsg(Exceptions::FileOperationFailed,
+                        "Symbolic link creating is not done.");
+            }
+        }
+
+        /* link for data directory */
+        std::string storagePath = m_context.locations->getPrivateStorageDir();
+        std::string dataDir = m_context.locations->getPackageInstallationDir() +
+            "/" + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath();
+        if (0 != access(dataDir.c_str(), F_OK)) {
+            _D("Make symbolic name for preload app %s to %s", storagePath.c_str(), dataDir.c_str());
+
+            if (symlink(storagePath.c_str(), dataDir.c_str()) != 0)
+            {
+                int error = errno;
+                if (error)
+                    _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str());
+                ThrowMsg(Exceptions::FileOperationFailed,
+                        "Symbolic link creating is not done.");
+            }
+            changeOwnerForDirectory(dataDir, PRIVATE_STORAGE_MODE);
+        }
+
+        if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) {
+            std::string widgetBinPath = m_context.locations->getBinaryDir();
+            std::string userBinPath = m_context.locations->getUserBinaryDir();
+            _D("Make symbolic link for preload app %s to %s", widgetBinPath.c_str(), userBinPath.c_str());
+            if (symlink(widgetBinPath.c_str(), userBinPath.c_str()) != 0)
+            {
+                int error = errno;
+                if (error)
+                    _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str());
+                ThrowMsg(Exceptions::FileOperationFailed,
+                        "Symbolic link creating is not done.");
+            }
+
+        }
+    }
+}
+
+void TaskUserDataManipulation::StepCreateSharedFolder()
+{
+    _D("StepCreateSharedFolder");
+    std::string sharedPath = m_context.locations->getSharedRootDir();
+    _D("Create shared directory : %s", m_context.locations->getSharedRootDir().c_str());
+
+    WrtUtilMakeDir(sharedPath);
+    WrtUtilMakeDir(m_context.locations->getSharedResourceDir());
+
+    changeOwnerForDirectory(m_context.locations->getSharedDataDir(),
+            SHARED_STORAGE_MODE);
+    changeOwnerForDirectory(m_context.locations->getSharedTrustedDir(),
+            SHARED_STORAGE_MODE);
+
+
+    // additional check for rootPath installation
+    // If this app is preloaded, "shared" diretory is already on place and do not needs to be moved
+    // TODO: why "shared" is on RW partion always but "data" and "tmp" are linked
+    if (m_context.isUpdateMode
+            && !(m_context.mode.rootPath == InstallMode::RootPath::RO
+            && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD)) {
+
+        /* Restore /shared/data */
+        _D("copy %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str());
+        if (!DirectoryApi::DirectoryCopy(
+                    m_context.locations->getBackupSharedDataDir(),
+                    m_context.locations->getSharedDataDir())) {
+                _E("Failed to rename %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str());
+                ThrowMsg(Exceptions::BackupFailed,
+                        "Error occurs copy shared strage files");
+            }
+
+        /* Restore /shared/trusted */
+        _D("copy %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str());
+        if (!DirectoryApi::DirectoryCopy(
+                    m_context.locations->getBackupSharedTrustedDir(),
+                    m_context.locations->getSharedTrustedDir())) {
+            _E("Failed to rename %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str());
+            ThrowMsg(Exceptions::BackupFailed,
+                    "Error occurs copy shared strage files");
+        }
+    }
+}
+
+void TaskUserDataManipulation::StartStep()
+{
+    _D("--------- <TaskUserDataManipulation> : START ----------");
+}
+
+void TaskUserDataManipulation::EndStep()
+{
+    _D("--------- <TaskUserDataManipulation> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/task_user_data_manipulation.h b/src_mobile/jobs/widget_install/task_user_data_manipulation.h
new file mode 100644 (file)
index 0000000..fbfabcc
--- /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_user_data_manipulation.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task user data folder 
+ */
+#ifndef JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H
+#define JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H
+
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskUserDataManipulation :
+    public DPL::TaskDecl<TaskUserDataManipulation>
+{
+    InstallerContext& m_context;
+
+    void StartStep();
+    void EndStep();
+    void StepCreatePrivateStorageDir();
+    void StepCreateSharedFolder();
+    void StepLinkForPreload();
+
+  public:
+    TaskUserDataManipulation(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif //JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H 
diff --git a/src_mobile/jobs/widget_install/view_mode.h b/src_mobile/jobs/widget_install/view_mode.h
new file mode 100644 (file)
index 0000000..a4acc39
--- /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       view_mode.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_VIEW_MODE_H_
+#define SRC_JOBS_WIDGET_INSTALL_VIEW_MODE_H_
+
+namespace Jobs {
+namespace WidgetInstall {
+enum ViewMode
+{
+    WINDOWED = 0,
+    FLOATING,
+    FULLSCREEN,
+    MAXIMIZED,
+    MINIMIZED
+};
+} // WidgetInstall
+} // Jobs
+
+#endif /* SRC_JOBS_WIDGET_INSTALL_VIEW_MODE_H_ */
diff --git a/src_mobile/jobs/widget_install/widget_install_context.h b/src_mobile/jobs/widget_install/widget_install_context.h
new file mode 100644 (file)
index 0000000..967a737
--- /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.
+ */
+/**
+ * @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 <map>
+#include <string>
+#include <dpl/string.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <widget_install/widget_security.h>
+#include <feature_logic.h>
+#include <widget_install/widget_update_info.h>
+#include <widget_location.h>
+#include <wrt_install_mode.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class JobWidgetInstall;
+} //namespace Jobs
+} //namespace WidgetInstall
+
+class WidgetModel;
+
+typedef std::map<DPL::String, bool> RequestedDevCapsMap;
+
+struct InstallerContext
+{
+    typedef enum InstallStepEnum
+    {
+        INSTALL_START = 0,
+        INSTALL_PARSE_CONFIG,
+        INSTALL_CHECK_FILE,
+
+        INSTALL_RDS_DELTA_CHECK,
+        INSTALL_RDS_PREPARE,
+
+        INSTALL_CREATE_BACKUP_DIR,                     /* For Update */
+        INSTALL_DIR_CREATE,
+        INSTALL_UNZIP_WGT,
+        INSTALL_WIDGET_CONFIG1,
+        INSTALL_WIDGET_CONFIG2,
+        INSTALL_DIGSIG_CHECK,
+        INSTALL_CERT_CHECK,
+        INSTALL_CERTIFY_LEVEL_CHECK,
+        INSTALL_ECRYPTION_FILES,
+        INSTALL_BACKUP_ICONFILE,                         /* For Update */
+        INSTALL_COPY_ICONFILE,
+        INSTALL_COPY_LIVEBOX_FILES,
+        INSTALL_CREATE_EXECFILE,
+        INSTALL_CREATE_MANIFEST,
+        INSTALL_INSTALL_OSPSVC,
+        INSTALL_NEW_DB_INSERT,
+        INSTALL_ACE_PREPARE,
+        INSTALL_ACE_CHECK,
+        INSTALL_SMACK_ENABLE,
+        INSTALL_PKGINFO_UPDATE,
+        INSTALL_SET_CERTINFO,
+
+        INSTALL_END
+    } InstallStep;
+
+    // Installation state variables
+    WrtDB::WidgetRegisterInfo widgetConfig;      ///< WidgetConfigInfo
+    DPL::Optional<WidgetLocation> locations;
+    Jobs::WidgetInstall::WidgetSecurity widgetSecurity; ///< Widget Domain
+                                                  // information.
+    InstallStep installStep;              ///< current step of installation
+    Jobs::WidgetInstall::JobWidgetInstall *job;
+     ///< Whether this is an update or normal installation
+    Jobs::WidgetInstall::FeatureLogicPtr featureLogic;
+    /** List of dev-caps that are requested in widget config file.
+     * Additional flag tells whether dev cap gets "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). */
+    RequestedDevCapsMap staticPermittedDevCaps;
+    std::string installInfo;            ///<For recovery>
+    InstallLocationType locationType;
+    bool isUpdateMode;
+    InstallMode mode;
+    DPL::String callerPkgId;
+
+    std::string requestedPath; ///input path of widget
+    bool needEncryption;  ///for configuring right task if encryption needed
+    int certLevel;
+};
+
+#endif // INSTALLER_CONTEXT_H
diff --git a/src_mobile/jobs/widget_install/widget_install_errors.h b/src_mobile/jobs/widget_install/widget_install_errors.h
new file mode 100644 (file)
index 0000000..ed0e6fb
--- /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    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>
+#include <job_exception_error.h>
+
+//TODO SafeException(...)
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace Exceptions {
+
+DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown)
+
+DECLARE_JOB_EXCEPTION(Base, OpenZipFailed, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, ZipEmpty, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, ExtractFileFailed, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, EmptyPluginsDirectory, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, PluginsSubdirectory, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, RDSDeltaFailure, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, MissingConfig, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, InvalidStartFile, ErrorPackageInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, PackageLowerVersion, ErrorPackageLowerVersion)
+
+DECLARE_JOB_EXCEPTION(Base, ManifestInvalid, ErrorManifestInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, WidgetConfigFileNotFound, ErrorConfigNotFound)
+DECLARE_JOB_EXCEPTION(Base, WidgetConfigFileInvalid, ErrorConfigInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, SignatureNotFound, ErrorSignatureNotFound)
+
+DECLARE_JOB_EXCEPTION(Base, SignatureInvalid, ErrorSignatureInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, SignatureVerificationFailed, ErrorSignatureVerificationFailed)
+
+DECLARE_JOB_EXCEPTION(Base, RootCertificateNotFound, ErrorRootCertificateNotFound)
+
+DECLARE_JOB_EXCEPTION(Base, CertificationInvaid, ErrorCertificationInvaid)
+DECLARE_JOB_EXCEPTION(Base, NotMatchedCertification, ErrorCertificationInvaid)
+
+DECLARE_JOB_EXCEPTION(Base, CertificateChainVerificationFailed, ErrorCertificateChainVerificationFailed)
+
+DECLARE_JOB_EXCEPTION(Base, CertificateExpired, ErrorCertificateExpired)
+
+DECLARE_JOB_EXCEPTION(Base, NotAllowed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, WidgetRunningError, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, DrmDecryptFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, RemovingFolderFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, RemovingFileFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, CreateVconfFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, CopyIconFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, FileOperationFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, InstallToExternalFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, BackupFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, InsertNewWidgetFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, RemoveBackupFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, UpdateFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, SetCertificateInfoFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, ErrorExternalInstallingFailure, ErrorFatalError)
+
+DECLARE_JOB_EXCEPTION(Base, PackageAlreadyInstalled, ErrorPackageAlreadyInstalled)
+DECLARE_JOB_EXCEPTION(Base, AceCheckFailed, ErrorAceCheckFailed)
+DECLARE_JOB_EXCEPTION(Base, EncryptionFailed, ErrorEncryptionFailed)
+DECLARE_JOB_EXCEPTION(Base, InstallOspsvcFailed, ErrorInstallOspServcie)
+DECLARE_JOB_EXCEPTION(Base, PrivilegeLevelViolation, ErrorPrivilegeLevelViolation)
+DECLARE_JOB_EXCEPTION(Base, NotSupportRDSUpdate, ErrorNotSupportRDSUpdate)
+DECLARE_JOB_EXCEPTION(Base, SmackTransactionFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, OutOfStorageFailed, ErrorOutOfStorage)
+} //namespace
+} //namespace
+} //namespace
+
+#endif /* INSTALLER_ERRORS_H_ */
diff --git a/src_mobile/jobs/widget_install/widget_installer_struct.h b/src_mobile/jobs/widget_install/widget_installer_struct.h
new file mode 100644 (file)
index 0000000..1fd865e
--- /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    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_install_mode.h>
+#include <wrt_common_types.h>
+#include <pkgmgr_signal_interface.h>
+#include <memory>
+#include <string>
+
+//Widget Installer typedefs
+typedef void (*InstallerFinishedCallback)(
+    void *userParam,
+    std::string tizenId,
+    Jobs::Exceptions::Type);
+
+typedef void (*InstallerProgressCallback)(void *userParam,
+                                          ProgressPercent percent,
+                                          const ProgressDescription &);
+
+namespace Jobs {
+namespace WidgetInstall {
+//InstallationStruct
+typedef Jobs::JobCallbacksBase<InstallerFinishedCallback,
+                               InstallerProgressCallback>
+WidgetInstallCallbackBase;
+
+//Widget Installation Struct
+struct WidgetInstallationStruct : public WidgetInstallCallbackBase
+{
+    InstallMode m_installMode;
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgmgrInterface;
+
+    // It must be empty-constructible as a parameter of generic event
+    WidgetInstallationStruct() {};
+    WidgetInstallationStruct(
+        InstallerFinishedCallback finished,
+        InstallerProgressCallback progress,
+        void *param,
+        InstallMode mode,
+        std::shared_ptr<PackageManager::IPkgmgrSignal>
+        _pkgmgrInterface
+        ) :
+        WidgetInstallCallbackBase(finished, progress, param),
+        m_installMode(mode),
+        pkgmgrInterface(_pkgmgrInterface)
+    {}
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+
+#endif // WRT_SRC_INSTALLER_CORE_INSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_
diff --git a/src_mobile/jobs/widget_install/widget_security.cpp b/src_mobile/jobs/widget_install/widget_security.cpp
new file mode 100644 (file)
index 0000000..01644ab
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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_security.cpp
+ * @author  Krzysztof Jackiewicz(k.jackiewicz@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+#include "widget_security.h"
+#include <dpl/foreach.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+void WidgetSecurity::getCertificateChainList(
+    WrtDB::CertificateChainList& list,
+    WrtDB::CertificateSource source) const
+{
+    if (source == WrtDB::CertificateSource::SIGNATURE_DISTRIBUTOR) {
+        FOREACH(certIter, mCertificateChainList)
+        list.push_back(certIter->toBase64String());
+    } else {
+        FOREACH(certIter, mAuthorsCertificateChainList)
+        list.push_back(certIter->toBase64String());
+    }
+}
+} // namespace WidgetInstall
+} // namespace Jobs
diff --git a/src_mobile/jobs/widget_install/widget_security.h b/src_mobile/jobs/widget_install/widget_security.h
new file mode 100644 (file)
index 0000000..0bc04ef
--- /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.
+ */
+/*
+ * @file    widget_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 WidgetSecurity : public WrtDB::IWidgetSecurity
+{
+  public:
+    WidgetSecurity() :
+        mRecognized(false),
+        mDistributorSigned(false)
+    {}
+
+    // from IWidgetSecurity
+    virtual const WrtDB::WidgetCertificateDataList& getCertificateList() const
+    {
+        return mCertificateList;
+    }
+
+    virtual bool isRecognized() const
+    {
+        return mRecognized;
+    }
+
+    virtual bool isDistributorSigned() const
+    {
+        return mDistributorSigned;
+    }
+
+    virtual void getCertificateChainList(
+        WrtDB::CertificateChainList& list,
+        WrtDB::CertificateSource source) const;
+
+    void setRecognized(bool recognized)
+    {
+        mRecognized = recognized;
+    }
+    void setDistributorSigned(bool distributorSigned)
+    {
+        mDistributorSigned = distributorSigned;
+    }
+    void setAuthorCertificatePtr(ValidationCore::CertificatePtr certPtr)
+    {
+        mAuthorCertificate = certPtr;
+    }
+
+    ValidationCore::CertificatePtr getAuthorCertificatePtr() const
+    {
+        return mAuthorCertificate;
+    }
+    ValidationCore::CertificateCollectionList& getCertificateChainListRef()
+    {
+        return mCertificateChainList;
+    }
+
+    ValidationCore::CertificateCollectionList&
+    getAuthorsCertificateChainListRef()
+    {
+        return mAuthorsCertificateChainList;
+    }
+
+    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;
+    // 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;
+    // This authors certificates are used by tizen
+    ValidationCore::CertificateCollectionList mAuthorsCertificateChainList;
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+
+#endif /* WACSECURITY_H_ */
diff --git a/src_mobile/jobs/widget_install/widget_unzip.cpp b/src_mobile/jobs/widget_install/widget_unzip.cpp
new file mode 100644 (file)
index 0000000..057b6c3
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * 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_unzip.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer widget unzip
+ */
+#include <widget_install/widget_unzip.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/job_widget_install.h>
+#include <dpl/copy.h>
+#include <dpl/file_output.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <task_commons.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <dlfcn.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const char *const DRM_LIB_PATH = "/usr/lib/libdrm-service-core-tizen.so";
+const size_t SPACE_SIZE = 1024 * 1024;
+const char *const WEB_APP_CONFIG_XML= "config.xml";
+const char *const HYBRID_CONFIG_XML = "res/wgt/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));
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+
+WidgetUnzip::WidgetUnzip(const std::string &source)
+{
+    Try {
+        m_requestFile = getDecryptedPackage(source);
+        m_zip.reset(new DPL::ZipInput(m_requestFile));
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, source);
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, source);
+    }
+}
+
+void WidgetUnzip::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 WidgetUnzip::unzipProgress(const std::string &destination)
+{
+    // Show file info
+    _D("Unzipping: '%s', Comment: '%s', Compressed size: %lld, Uncompressed size: %lld",
+            m_zipIterator->name.c_str(), m_zipIterator->comment.c_str(), m_zipIterator->compressedSize, 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 = destination + "/" +
+            fileName.substr(0, fileName.size() - 1);
+        _D("Path to extract: %s", newPath.c_str());
+
+        // Create path in case of it is empty
+        createTempPath(newPath);
+    } else {
+        // This is regular file
+        std::string fileExtractPath = destination + "/" + fileName;
+
+        _D("File to extract: %s", fileExtractPath.c_str());
+
+        // Split into pat & file pair
+        PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath);
+
+        _D("Path and file: %s : %s", pathAndFile.path.c_str(), pathAndFile.file.c_str());
+
+        // First, ensure that path exists
+        createTempPath(pathAndFile.path);
+
+        Try
+        {
+            // Open file
+            std::unique_ptr<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()) {
+        _D("Unzip progress finished successfuly");
+    } else {
+        unzipProgress(destination);
+    }
+}
+
+bool WidgetUnzip::isDRMPackage(const std::string &source)
+{
+    _D("Enter : isDRMPackage()");
+    int ret = 0;
+    void* pHandle = NULL;
+    char* pErrorMsg = NULL;
+    int (*drm_oem_sapps_is_drm_file)(const char* pDcfPath, int dcfPathLen);
+
+    pHandle = dlopen(DRM_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
+    if (!pHandle) {
+        _E("dlopen failed : %s [%s]", source.c_str(), dlerror());
+        return false;
+    }
+
+    // clear existing error
+    dlerror();
+
+    drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>
+        (dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
+
+    if ((pErrorMsg = dlerror()) != NULL) {
+        _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+        dlclose(pHandle);
+        return false;
+    }
+
+    if (drm_oem_sapps_is_drm_file == NULL) {
+        _E("drm_oem_sapps_is_drm_file is NULL : %s", source.c_str());
+        dlclose(pHandle);
+        return false;
+    }
+
+    ret = drm_oem_sapps_is_drm_file(source.c_str(), source.length());
+    dlclose(pHandle);
+    if (1 == ret) {
+        _D("%s is DRM file", source.c_str());
+        return true;
+    }
+    _D("%s isn't DRM file", source.c_str());
+    return false;
+}
+
+bool WidgetUnzip::decryptDRMPackage(const std::string &source, const std::string
+        &decryptedSource)
+{
+    _D("Enter : decryptDRMPackage()");
+    int ret = 0;
+    void* pHandle = NULL;
+    char* pErrorMsg = NULL;
+    int (*drm_oem_sapps_decrypt_package)(const char* pDcfPath, int dcfPathLen,
+            const char* pDecryptedFile, int decryptedFileLen);
+
+    pHandle = dlopen(DRM_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
+    if (!pHandle) {
+        _E("dlopen failed : %s [%s]", source.c_str(), dlerror());
+        return false;
+    }
+
+    // clear existing error
+    dlerror();
+
+    drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int,
+            const char*, int)>
+        (dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
+
+    if ((pErrorMsg = dlerror()) != NULL) {
+        _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+        dlclose(pHandle);
+        return false;
+    }
+
+    if (drm_oem_sapps_decrypt_package == NULL) {
+        _E("drm_oem_sapps_decrypt_package is NULL : %s", source.c_str());
+        dlclose(pHandle);
+        return false;
+    }
+
+    ret = drm_oem_sapps_decrypt_package(source.c_str(), source.length(),
+            decryptedSource.c_str(), decryptedSource.length());
+    dlclose(pHandle);
+    if (1 == ret) {
+        _D("%s is decrypted : %s", source.c_str(), decryptedSource.c_str());
+        return true;
+    }
+    return false;
+}
+
+std::string WidgetUnzip::getDecryptedPackage(const std::string &source)
+{
+    _D("Check DRM...");
+    if (isDRMPackage(source)) {
+        std::string decryptedFile;
+        size_t found = source.find_last_of(".wgt");
+        if (found == std::string::npos) {
+            decryptedFile += source + "_tmp.wgt";
+        } else {
+            decryptedFile += source.substr(0, source.find_last_not_of(".wgt") +
+                    1) + "_tmp.wgt";
+        }
+
+        _D("decrypted file name : %s", decryptedFile.c_str());
+        if (!decryptDRMPackage(source, decryptedFile)) {
+            _E("Failed decrypt drm file");
+            ThrowMsg(Exceptions::DrmDecryptFailed, source);
+        }
+        return decryptedFile;
+    }
+    return source;
+}
+
+void WidgetUnzip::unzipWgtFile(const std::string &destination)
+{
+    _D("Prepare to unzip...");
+    Try
+    {
+        _D("wgtFile : %s", m_requestFile.c_str());
+        _D("Widget package comment: %s", m_zip->GetGlobalComment().c_str());
+
+        // Widget package must not be empty
+        if (m_zip->empty()) {
+            ThrowMsg(Exceptions::ZipEmpty, m_requestFile);
+        }
+
+        // Set iterator to first file
+        m_zipIterator = m_zip->begin();
+
+        unzipProgress(destination);
+
+        // Unzip finished, close internal structures
+        m_zip.reset();
+
+        // Done
+        _D("Unzip finished");
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, m_requestFile);
+    }
+    Catch(DPL::ZipInput::Exception::SeekFileFailed)
+    {
+        ThrowMsg(Exceptions::ExtractFileFailed, m_requestFile);
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, m_requestFile);
+    }
+}
+
+bool WidgetUnzip::checkAvailableSpace(const std::string &destination)
+{
+    _D("checkAvailableSpace ... ");
+
+    double unCompressedSize = m_zip->GetTotalUncompressedSize();
+    _D("unCompressedSize : %ld", unCompressedSize);
+
+    struct statvfs vfs;
+    if (-1 == statvfs(destination.c_str(), &vfs)) {
+        _E("There is no space for installation");
+        return false;
+    }
+
+    double freeSize = (double)vfs.f_bsize * vfs.f_bavail;
+    _D("Space Size : %ld", freeSize);
+
+    if (unCompressedSize + SPACE_SIZE >= freeSize) {
+        _E("There is no space for installation");
+        return false;
+    }
+    return true;
+}
+
+void WidgetUnzip::unzipConfiguration(const std::string &destination,
+        WrtDB::PackagingType* type)
+{
+    _D("unzipConfiguration");
+
+    Try {
+        _D("wgtFile : %s", m_requestFile.c_str());
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        Try {
+            configFile.reset(m_zip->OpenFile(HYBRID_CONFIG_XML));
+            *type = PKG_TYPE_HYBRID_WEB_APP;
+        } Catch(DPL::ZipInput::Exception::OpenFileFailed) {
+            configFile.reset(m_zip->OpenFile(WEB_APP_CONFIG_XML));
+            *type = PKG_TYPE_NOMAL_WEB_APP;
+        }
+
+        std::string extractPath = destination + "/" + WEB_APP_CONFIG_XML;
+        ExtractFile(configFile.get(), extractPath);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, m_requestFile);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        ThrowMsg(Exceptions::ExtractFileFailed, "config.xml");
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, m_requestFile);
+    }
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_install/widget_unzip.h b/src_mobile/jobs/widget_install/widget_unzip.h
new file mode 100644 (file)
index 0000000..204cde7
--- /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    widget_unzip.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task unzip
+ */
+#ifndef WIDGET_UNZIP_H
+#define WIDGET_UNZIP_H
+
+#include <string>
+
+#include <dpl/zip_input.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class WidgetUnzip 
+{
+  public:
+      WidgetUnzip(const std::string &source);
+      void unzipWgtFile(const std::string &destination);
+      void unzipConfiguration(const std::string &destination, WrtDB::PackagingType *type);
+      bool checkAvailableSpace(const std::string &destination);
+
+  private:
+    // Unzip state
+    std::unique_ptr<DPL::ZipInput> m_zip;
+    DPL::ZipInput::const_iterator m_zipIterator;
+    std::string m_requestFile;
+
+    void unzipProgress(const std::string &destination);
+    void ExtractFile(DPL::ZipInput::File *input, const std::string
+            &destFileName);
+    bool isDRMPackage(const std::string &source);
+    bool decryptDRMPackage(const std::string &source, const std::string
+            &decryptedSource);
+    std::string getDecryptedPackage(const std::string &source);
+};
+
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // WIDGET_UNZIP_H
diff --git a/src_mobile/jobs/widget_install/widget_update_info.cpp b/src_mobile/jobs/widget_install/widget_update_info.cpp
new file mode 100644 (file)
index 0000000..621907b
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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::WidgetUpdateInfo(
+    const WrtDB::TizenAppId & appId,
+    const DPL::Optional<WidgetVersion> &existingversion,
+    const DPL::Optional<WidgetVersion> &incomingversion) :
+      tzAppId(appId),
+      existingVersion(existingversion),
+      incomingVersion(incomingversion)
+{
+}
+
diff --git a/src_mobile/jobs/widget_install/widget_update_info.h b/src_mobile/jobs/widget_install/widget_update_info.h
new file mode 100644 (file)
index 0000000..21004bd
--- /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    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
+{
+    WrtDB::TizenAppId tzAppId;
+    // Existing widget
+    DPL::Optional<WidgetVersion> existingVersion;
+    // Incoming widget
+    DPL::Optional<WidgetVersion> incomingVersion;
+
+    WidgetUpdateInfo() {};
+    WidgetUpdateInfo(const WrtDB::TizenAppId & tzAppid,
+                     const DPL::Optional<WidgetVersion> &existringversion,
+                     const DPL::Optional<WidgetVersion> &incomingVersion);
+};
+
+#endif // SRC_DOMAIN_WIDGET_UPDATE_INFO_H
diff --git a/src_mobile/jobs/widget_uninstall/job_widget_uninstall.cpp b/src_mobile/jobs/widget_uninstall/job_widget_uninstall.cpp
new file mode 100644 (file)
index 0000000..71de26f
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * 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 <regex.h>
+#include <sys/stat.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/widget_uninstall_errors.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_remove_custom_handlers.h>
+#include <widget_uninstall/task_smack.h>
+#include <widget_uninstall/task_uninstall_ospsvc.h>
+#include <widget_uninstall/task_delete_pkginfo.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <pkg-manager/pkgmgr_signal.h>
+#include <app2ext_interface.h>
+#include <dpl/utils/path.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace { //anonymous
+const char* REG_TIZEN_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
+const int PKGID_LENTH = 10;
+const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps");
+
+bool checkDirectoryExist(const std::string& pkgId)
+{
+    DPL::Utils::Path installPath(GlobalConfig::GetUserInstalledWidgetPath());
+    installPath /= pkgId;
+    return installPath.Exists();
+}
+}
+
+namespace Jobs {
+namespace WidgetUninstall {
+
+class UninstallerTaskFail :
+    public DPL::TaskDecl<UninstallerTaskFail>
+{
+  private:
+    WidgetStatus m_status;
+
+    void StepFail()
+    {
+        if (WidgetStatus::NOT_INSTALLED == m_status) {
+            ThrowMsg(Jobs::WidgetUninstall::Exceptions::WidgetNotExist,
+                     "Widget does not exist");
+        } else if (WidgetStatus::PREALOAD == m_status) {
+            ThrowMsg(Jobs::WidgetUninstall::Exceptions::Unremovable,
+                     "Widget cann't uninstall");
+        } else {
+            Throw(Jobs::WidgetUninstall::Exceptions::Base);
+        }
+    }
+
+  public:
+    UninstallerTaskFail(WidgetStatus status) :
+        DPL::TaskDecl<UninstallerTaskFail>(this),
+        m_status(status)
+
+    {
+        AddStep(&UninstallerTaskFail::StepFail);
+    }
+};
+
+JobWidgetUninstall::JobWidgetUninstall(
+    const std::string & tizenAppId,
+    const WidgetUninstallationStruct &
+    uninstallerStruct) :
+    Job(Uninstallation),
+    JobContextBase<WidgetUninstallationStruct>(uninstallerStruct),
+    m_exceptionCaught(Jobs::Exceptions::Success)
+{
+    using namespace PackageManager;
+    m_context.removeStarted = false;
+    m_context.removeFinished = false;
+    m_context.removeAbnormal = false;
+    m_context.uninstallStep = UninstallerContext::UNINSTALL_START;
+    m_context.job = this;
+
+    Try
+    {
+        WidgetStatus status = getWidgetStatus(tizenAppId);
+
+        if (WidgetStatus::Ok == status) {
+            WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(m_context.tzAppid));
+            m_context.tzPkgid = DPL::ToUTF8String(dao.getTizenPkgId());
+            m_context.locations = WidgetLocation(m_context.tzPkgid);
+            m_context.locations->registerAppid(m_context.tzAppid);
+            m_context.installedPath =
+                DPL::Utils::Path(*dao.getWidgetInstalledPath());
+            m_context.manifestFile = getManifestFile();
+
+            _D("Widget model exists. App id : %s", m_context.tzAppid.c_str());
+
+            // send start signal of pkgmgr
+            if (GetInstallerStruct().pkgmgrInterface->setPkgname(m_context.tzPkgid))
+            {
+                GetInstallerStruct().pkgmgrInterface->startJob(InstallationType::Uninstallation);
+            }
+
+            AddTask(new TaskCheck(m_context));
+            if (dao.getPackagingType() == PKG_TYPE_HYBRID_WEB_APP) {
+                AddTask(new TaskUninstallOspsvc(m_context));
+            }
+            AddTask(new TaskDeletePkgInfo(m_context));
+            AddTask(new TaskDbUpdate(m_context));
+            AddTask(new TaskSmack(m_context));
+
+            AddTask(new TaskRemoveCustomHandlers(m_context));
+            AddTask(new TaskRemoveFiles(m_context));
+        } else if (WidgetStatus::NOT_INSTALLED == status ||
+                WidgetStatus::PREALOAD == status) {
+            AddTask(new UninstallerTaskFail(status));
+        } else if (WidgetStatus::ABNORMAL == status) {
+            m_context.locations = WidgetLocation(m_context.tzPkgid);
+            m_context.removeAbnormal = true;
+            AddTask(new TaskRemoveFiles(m_context));
+        } else {
+            AddTask(new UninstallerTaskFail(WidgetStatus::UNRECOGNIZED));
+        }
+    } Catch(WidgetDAOReadOnly::Exception::Base) {
+        AddTask(new UninstallerTaskFail(WidgetStatus::UNRECOGNIZED));
+    }
+}
+
+WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id)
+{
+    regex_t regx;
+    if(regcomp(&regx, REG_TIZEN_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
+        _D("Regcomp failed");
+    }
+    std::string pkgId;
+    DPL::Utils::Path installPath;
+
+    Try {
+        if ((regexec(&regx, id.c_str(),
+                        static_cast<size_t>(0), NULL, 0) == REG_NOERROR)) {
+            pkgId = id;
+
+            TizenAppId appid =
+                WrtDB::WidgetDAOReadOnly::getTzAppId(
+                        DPL::FromUTF8String(id));
+            _D("Get appid from pkgid : %ls", appid.c_str());
+            m_context.tzAppid = DPL::ToUTF8String(appid);
+            WrtDB::WidgetDAOReadOnly dao(appid);
+            installPath = DPL::Utils::Path(*dao.getWidgetInstalledPath());
+        } else {
+            pkgId = id.substr(0, PKGID_LENTH);
+            WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(id));
+            m_context.tzAppid = id;
+            installPath = DPL::Utils::Path(*dao.getWidgetInstalledPath());
+        }
+        if(installPath.isSubPath(PRELOAD_INSTALLED_PATH)){
+            _D("This widget is preloaded.");
+        }
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        _D("package id : %s", pkgId.c_str());
+        m_context.tzPkgid = pkgId;
+        if (!pkgId.empty()) {
+            if(checkDirectoryExist(pkgId)) {
+                _E("installed widget status is abnormal");
+                return WidgetStatus::ABNORMAL;
+            }
+        }
+        return WidgetStatus::NOT_INSTALLED;
+    }
+    return WidgetStatus::Ok;
+}
+
+std::string JobWidgetUninstall::getRemovedTizenId() const
+{
+    return m_context.tzAppid;
+}
+
+bool JobWidgetUninstall::getRemoveStartedFlag() const
+{
+    return m_context.removeStarted;
+}
+
+bool JobWidgetUninstall::getRemoveFinishedFlag() const
+{
+    return m_context.removeFinished;
+}
+
+DPL::Utils::Path JobWidgetUninstall::getManifestFile() const
+{
+    std::ostringstream manifest_name;
+    manifest_name << m_context.tzPkgid << ".xml";
+    DPL::Utils::Path manifestFile;
+
+    const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps/" + m_context.tzPkgid);
+    const DPL::Utils::Path USR_PACKAGES_PATH("/usr/share/packages");
+    const DPL::Utils::Path OPT_PACKAGES_PATH("/opt/share/packages");
+
+    if (PRELOAD_INSTALLED_PATH == m_context.installedPath) {
+        _D("This widget is preloaded.");
+        manifestFile = USR_PACKAGES_PATH;
+    } else {
+        manifestFile = OPT_PACKAGES_PATH;
+    }
+
+    manifestFile /= manifest_name.str();
+    _D("Manifest file : %s", manifestFile.Fullpath().c_str());
+
+    return manifestFile;
+}
+
+void JobWidgetUninstall::SendProgress()
+{
+    using namespace PackageManager;
+    if (!getRemoveStartedFlag() ||
+        (getRemoveStartedFlag() && getRemoveFinishedFlag()))
+    {
+        if (NULL != GetInstallerStruct().progressCallback) {
+            // send progress signal of pkgmgr
+            std::ostringstream percent;
+            percent << static_cast<int>(GetProgressPercent());
+
+            _D("Call widget uninstall progressCallback");
+            GetInstallerStruct().progressCallback(
+                GetInstallerStruct().userParam,
+                GetProgressPercent(), GetProgressDescription());
+        }
+    }
+}
+
+void JobWidgetUninstall::SendFinishedSuccess()
+{
+    using namespace PackageManager;
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    _D("Call widget uninstall success finishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          getRemovedTizenId(),
+                                          Jobs::Exceptions::Success);
+}
+
+void JobWidgetUninstall::SendFinishedFailure()
+{
+    using namespace PackageManager;
+    _E("Error in uninstallation step: %d", m_exceptionCaught);
+    _E("Message: %s", m_exceptionMessage.c_str());
+
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    _D("Call widget uninstall failure finishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          getRemovedTizenId(),
+                                          m_exceptionCaught);
+    _D("[JobWidgetUninstall] Asynchronous failure callback status sent");
+}
+
+void JobWidgetUninstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
+{
+    m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
+    m_exceptionMessage = e.GetMessage();
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/job_widget_uninstall.h b/src_mobile/jobs/widget_uninstall/job_widget_uninstall.h
new file mode 100644 (file)
index 0000000..21bb764
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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 <string>
+#include <job.h>
+#include <job_base.h>
+#include <widget_uninstall/widget_uninstaller_struct.h>
+#include <widget_uninstall/uninstaller_context.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+
+enum class WidgetStatus
+{
+    Ok, NOT_INSTALLED, PREALOAD, ABNORMAL, UNRECOGNIZED
+};
+
+typedef JobContextBase<WidgetUninstallationStruct> WidgetUnistallStructBase;
+typedef JobProgressBase<UninstallerContext::UninstallStep, UninstallerContext::UNINSTALL_END> UninstallContextBase;
+
+class JobWidgetUninstall :
+    public Job,
+    public UninstallContextBase,
+    public WidgetUnistallStructBase
+{
+  private:
+    UninstallerContext m_context;
+
+    //TODO move it to base class of all jobs
+    Jobs::Exceptions::Type m_exceptionCaught;
+    std::string m_exceptionMessage;
+
+  public:
+    /**
+     * @brief Uninstaller must to know which widget to uninstall.
+     *
+     * @param[in] WrtDB::TizenAppId tzAppId - widget to uninstall
+     */
+    JobWidgetUninstall(const std::string &tizenAppId,
+                       const WidgetUninstallationStruct& uninstallerStruct);
+
+    std::string getRemovedTizenId() const;
+    bool getRemoveStartedFlag() const;
+    bool getRemoveFinishedFlag() const;
+    DPL::Utils::Path getManifestFile() const;
+
+    WidgetStatus getWidgetStatus(const std::string &appId);
+
+    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_mobile/jobs/widget_uninstall/task_check.cpp b/src_mobile/jobs/widget_uninstall/task_check.cpp
new file mode 100644 (file)
index 0000000..22a7e91
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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 <ctime>
+#include <dpl/sstream.h>
+#include <widget_uninstall/task_check.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <app_manager.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskCheck::TaskCheck(UninstallerContext& context) :
+    DPL::TaskDecl<TaskCheck>(this),
+    m_context(context)
+{
+    AddStep(&TaskCheck::StartStep);
+    AddStep(&TaskCheck::StepUninstallPreCheck);
+    AddStep(&TaskCheck::StepCheckMDM);
+    AddStep(&TaskCheck::EndStep);
+}
+
+TaskCheck::~TaskCheck()
+{}
+
+void TaskCheck::StartStep()
+{
+    _D("--------- <TaskCheck> : START ----------");
+}
+
+void TaskCheck::EndStep()
+{
+    m_context.job->UpdateProgress(UninstallerContext::UNINSTALL_PRECHECK,
+                                  "Uninstall pre-checking Finished");
+    _D("--------- <TaskCheck> : END ----------");
+}
+
+void TaskCheck::StepUninstallPreCheck()
+{
+    bool isRunning = false;
+    int ret = app_manager_is_running(m_context.tzAppid.c_str(), &isRunning);
+    if (APP_MANAGER_ERROR_NONE != ret) {
+        _E("Fail to get running state");
+        ThrowMsg(Exceptions::PlatformAPIFailure,
+                 "Fail to get widget state");
+    }
+
+    if (true == isRunning) {
+        // get app_context for running application
+        // app_context must be released with app_context_destroy
+        app_context_h appCtx = NULL;
+        ret = app_manager_get_app_context(m_context.tzAppid.c_str(), &appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to get app_context");
+            ThrowMsg(Exceptions::AppIsRunning,
+                     "Widget is not stopped. Cannot uninstall!");
+        }
+
+        // terminate app_context_h
+        ret = app_manager_terminate_app(appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to terminate running application");
+            app_context_destroy(appCtx);
+            ThrowMsg(Exceptions::AppIsRunning,
+                     "Widget is not stopped. Cannot uninstall!");
+        } else {
+            app_context_destroy(appCtx);
+            // app_manager_terminate_app isn't sync API
+            // wait until application isn't running (50ms * 100)
+            bool isStillRunning = true;
+            int checkingloop = 100;
+            struct timespec duration = { 0, 50 * 1000 * 1000 };
+            while (--checkingloop >= 0) {
+                nanosleep(&duration, NULL);
+                int ret = app_manager_is_running(m_context.tzAppid.c_str(), &isStillRunning);
+                if (APP_MANAGER_ERROR_NONE != ret) {
+                    _E("Fail to get running state");
+                    ThrowMsg(Exceptions::PlatformAPIFailure,
+                             "Fail to get widget state");
+                }
+                if (!isStillRunning) {
+                    break;
+                }
+            }
+            if (isStillRunning) {
+                _E("Fail to terminate running application");
+                ThrowMsg(Exceptions::AppIsRunning,
+                         "Widget is not stopped. Cannot uninstall!");
+            }
+            _D("terminate application");
+        }
+    }
+
+    _D("Widget Can be uninstalled, Pkgname : %s", m_context.tzAppid.c_str());
+}
+
+void TaskCheck::StepCheckMDM()
+{
+    _D("StepCheckMDM");
+
+    if (PMINFO_R_OK !=  pkgmgr_parser_check_mdm_policy_for_uninstallation(
+                m_context.manifestFile.Fullpath().c_str())) {
+        _E("Failed to check mdm policy");
+        ThrowMsg(Exceptions::CheckMDMPolicyFailure, "Can't uninstall! Because of MDM policy");
+    }
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_check.h b/src_mobile/jobs/widget_uninstall/task_check.h
new file mode 100644 (file)
index 0000000..29c00db
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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();
+    void StepCheckMDM();
+    void StartStep();
+    void EndStep();
+
+  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_mobile/jobs/widget_uninstall/task_db_update.cpp b/src_mobile/jobs/widget_uninstall/task_db_update.cpp
new file mode 100644 (file)
index 0000000..f38280d
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * 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 <web_provider_livebox_info.h>
+#include <widget_uninstall/task_db_update.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <ace_api_install.h>
+#include <dpl/assert.h>
+#include <ace-common/ace_api_common.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskDbUpdate::TaskDbUpdate(UninstallerContext& context) :
+    DPL::TaskDecl<TaskDbUpdate>(this),
+    m_context(context)
+{
+    AddStep(&TaskDbUpdate::StartStep);
+    AddStep(&TaskDbUpdate::StepRemoveExternalLocations);
+    AddStep(&TaskDbUpdate::StepDbUpdate);
+    AddStep(&TaskDbUpdate::StepLiveboxDBDelete);
+    AddStep(&TaskDbUpdate::EndStep);
+}
+
+TaskDbUpdate::~TaskDbUpdate()
+{}
+
+void TaskDbUpdate::StepDbUpdate()
+{
+    Try
+    {
+        //TODO: widget handle should not be used any more
+        ace_unregister_widget(static_cast<ace_widget_handle_t>(
+                                  WidgetDAOReadOnly::getHandle(DPL::
+                                                                   FromUTF8String(
+                                                                   m_context.
+                                                                       tzAppid))));
+        WidgetDAO::unregisterWidget(DPL::FromUTF8String(m_context.tzAppid));
+
+        _D("Unregistered widget successfully!");
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base)
+    {
+        _E("Failed to handle StepDbUpdate!");
+        ReThrowMsg(Exceptions::DatabaseFailure,
+                   "Failed to handle StepDbUpdate!");
+    }
+}
+
+void TaskDbUpdate::StepLiveboxDBDelete()
+{
+    int ret =
+        web_provider_livebox_delete_by_app_id(m_context.tzAppid.c_str());
+
+    if (ret < 0) {
+        _D("failed to delete box info");
+    } else {
+        _D("delete box info: %s", m_context.tzAppid.c_str());
+    }
+}
+
+void TaskDbUpdate::StepRemoveExternalLocations()
+{
+    if (!m_context.removeAbnormal) {
+        WidgetDAO dao(DPL::FromUTF8String(m_context.tzAppid));
+        _D("Removing external locations:");
+        WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations();
+        FOREACH(file, externalPaths)
+        {
+            DPL::Utils::Path path(*file);
+            if(path.Exists()){
+                if(path.IsFile()){
+                    _D("  -> %s", path.Fullpath().c_str());
+                    Try{
+                        DPL::Utils::Remove(path);
+                    }Catch(DPL::Utils::Path::BaseException){
+                        _E("Failed to remove the file: %s", path.Fullpath().c_str());
+                    }
+                } else if (path.IsDir()){
+                    _D("  -> %s", path.Fullpath().c_str());
+                    Try{
+                        DPL::Utils::Remove(path);
+                    }Catch(DPL::Utils::Path::BaseException){
+                        Throw(Jobs::WidgetUninstall::TaskDbUpdate::
+                                Exception::RemoveFilesFailed);
+                    }
+                }
+            }else{
+                _W("  -> %s(no such a path)", path.Fullpath().c_str());
+            }
+        }
+        dao.unregisterAllExternalLocations();
+    }
+}
+
+void TaskDbUpdate::StartStep()
+{
+    _D("--------- <TaskDbUpdate> : START ----------");
+}
+
+void TaskDbUpdate::EndStep()
+{
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_DB_UPDATE,
+        "Widget DB Update Finished");
+
+    _D("--------- <TaskDbUpdate> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_db_update.h b/src_mobile/jobs/widget_uninstall/task_db_update.h
new file mode 100644 (file)
index 0000000..3b74ad5
--- /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_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 <string>
+#include <dpl/exception.h>
+#include <dpl/task.h>
+
+class UninstallerContext;
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskDbUpdate :
+    public DPL::TaskDecl<TaskDbUpdate>
+{
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, DbStepFailed)
+        DECLARE_EXCEPTION_TYPE(Base, RemoveFilesFailed)
+    };
+
+    UninstallerContext& m_context;
+
+  private:
+    void StepDbUpdate();
+    void StepLiveboxDBDelete();
+    void StepRemoveExternalLocations();
+
+    void StartStep();
+    void EndStep();
+
+  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_mobile/jobs/widget_uninstall/task_delete_pkginfo.cpp b/src_mobile/jobs/widget_uninstall/task_delete_pkginfo.cpp
new file mode 100644 (file)
index 0000000..88db8e2
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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_delete_pkginfo.cpp
+ * @author  Leerang Song(leerang.song@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for uninstaller delete package information
+ */
+
+#include <string.h>
+#include <widget_uninstall/task_delete_pkginfo.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <dpl/assert.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskDeletePkgInfo::TaskDeletePkgInfo(
+    UninstallerContext& context) :
+    DPL::TaskDecl<TaskDeletePkgInfo>(this),
+    m_context(context)
+{
+    AddStep(&TaskDeletePkgInfo::StartStep);
+    AddStep(&TaskDeletePkgInfo::StepDeletePkgInfo);
+    AddStep(&TaskDeletePkgInfo::EndStep);
+}
+
+void TaskDeletePkgInfo::StartStep()
+{
+    _D("--------- <TaskDeletePkgInfo> : START ----------");
+}
+
+void TaskDeletePkgInfo::EndStep()
+{
+    _D("--------- <TaskDeletePkgInfo> : END ----------");
+}
+
+void TaskDeletePkgInfo::StepDeletePkgInfo()
+{
+    std::ostringstream manifest_name;
+    manifest_name << m_context.tzPkgid << ".xml";
+    DPL::Utils::Path pre_manifest("/usr/share/packages");
+    pre_manifest /= manifest_name.str();
+
+    if (!(m_context.manifestFile.Exists() == 0 && pre_manifest.Exists())) {
+        if (0 !=  pkgmgr_parser_parse_manifest_for_uninstallation(
+                    m_context.manifestFile.Fullpath().c_str(), NULL)) {
+            _W("Manifest file failed to parse for uninstallation");
+        }
+    }
+    if (!DPL::Utils::TryRemove(m_context.manifestFile)) {
+        _W("No manifest file found: %s", m_context.manifestFile.Fullpath().c_str());
+    } else {
+        _D("Manifest file removed: %s", m_context.manifestFile.Fullpath().c_str());
+    }
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_delete_pkginfo.h b/src_mobile/jobs/widget_uninstall/task_delete_pkginfo.h
new file mode 100644 (file)
index 0000000..4624c4a
--- /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    task_delete_pkginfo.h
+ * @author  Leerang Song(leerang.song@samsung.com)
+ * @version 1.0
+ * @brief   Header file for uninstaller task delete package infomation
+ */
+
+#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DELETE_PKGINFO_H_
+#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DELETE_PKGINFO_H_
+
+#include <dpl/task.h>
+#include <string>
+
+struct UninstallerContext;
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskDeletePkgInfo :
+    public DPL::TaskDecl<TaskDeletePkgInfo>
+{
+    UninstallerContext& m_context;
+
+  private:
+    void StepDeletePkgInfo();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskDeletePkgInfo(UninstallerContext& context);
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif
+// WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DELETE_PKGINFO_H_
diff --git a/src_mobile/jobs/widget_uninstall/task_remove_custom_handlers.cpp b/src_mobile/jobs/widget_uninstall/task_remove_custom_handlers.cpp
new file mode 100644 (file)
index 0000000..f981b0c
--- /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    task_remove_custom_handlers.cpp
+ * @author  Przemyslaw Ciezkowski (p.ciezkowski@samsung.com)
+ * @version 1.0
+ * @brief   File for uninstaller - remove custom handlers
+ */
+
+#include <widget_uninstall/task_remove_custom_handlers.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <dpl/optional_typedefs.h>
+#include <appsvc.h>
+#include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
+#include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskRemoveCustomHandlers::TaskRemoveCustomHandlers(UninstallerContext& context)
+    :
+    DPL::TaskDecl<TaskRemoveCustomHandlers>(this),
+    m_context(context)
+{
+    AddStep(&TaskRemoveCustomHandlers::StartStep);
+    AddStep(&TaskRemoveCustomHandlers::Step);
+    AddStep(&TaskRemoveCustomHandlers::EndStep);
+}
+
+void TaskRemoveCustomHandlers::Step()
+{
+    _D("Removing widget from appsvc");
+    int result = appsvc_unset_defapp(m_context.tzAppid.c_str());
+    _D("Result: %d", result);
+
+    CustomHandlerDB::Interface::attachDatabaseRW();
+    CustomHandlerDB::CustomHandlerDAO handlersDao(
+        DPL::FromASCIIString(m_context.tzAppid));
+    handlersDao.removeWidgetProtocolHandlers();
+    handlersDao.removeWidgetContentHandlers();
+    CustomHandlerDB::Interface::detachDatabase();
+}
+
+void TaskRemoveCustomHandlers::StartStep()
+{
+    _D("--------- <TaskRemoveCustomHandlers> : START ----------");
+}
+
+void TaskRemoveCustomHandlers::EndStep()
+{
+    _D("--------- <TaskRemoveCustomHandlers> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_remove_custom_handlers.h b/src_mobile/jobs/widget_uninstall/task_remove_custom_handlers.h
new file mode 100644 (file)
index 0000000..e6458b9
--- /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_remove_custom_handlers.h
+ * @author  Przemyslaw Ciezkowski (p.ciezkowski@samsung.com)
+ * @version 1.0
+ * @brief   Header file for uninstaller - remove custom handlers
+ */
+#ifndef INSTALLER_CORE_JOBS_WIDGET_UNINSTALL_TASK_REMOVE_CUSTOM_HANDLERS_H
+#define INSTALLER_CORE_JOBS_WIDGET_UNINSTALL_TASK_REMOVE_CUSTOM_HANDLERS_H
+
+#include <dpl/task.h>
+
+class UninstallerContext;
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskRemoveCustomHandlers :
+    public DPL::TaskDecl<TaskRemoveCustomHandlers>
+{
+  private:
+    UninstallerContext& m_context;
+
+    void Step();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskRemoveCustomHandlers(UninstallerContext& context);
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOBS_WIDGET_UNINSTALL_TASK_REMOVE_CUSTOM_HANDLERS_H */
diff --git a/src_mobile/jobs/widget_uninstall/task_remove_files.cpp b/src_mobile/jobs/widget_uninstall/task_remove_files.cpp
new file mode 100644 (file)
index 0000000..f9f22de
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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 <unistd.h>
+#include <widget_uninstall/task_remove_files.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <ail.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <errno.h>
+#include <string.h>
+#include <widget_install_to_external.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+using namespace WrtDB;
+
+TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) :
+    DPL::TaskDecl<TaskRemoveFiles>(this),
+    m_context(context)
+{
+    AddStep(&TaskRemoveFiles::StartStep);
+    AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory);
+    AddStep(&TaskRemoveFiles::StepRemoveFinished);
+    AddStep(&TaskRemoveFiles::EndStep);
+}
+
+TaskRemoveFiles::~TaskRemoveFiles()
+{}
+
+void TaskRemoveFiles::StepRemoveInstallationDirectory()
+{
+    _D("StepRemoveInstallationDirectory started");
+    Try {
+        int ret = app2ext_get_app_location(m_context.tzPkgid.c_str());
+
+        if (APP2EXT_SD_CARD == ret) {
+            _D("Remove external directory");
+            Try {
+                WidgetInstallToExtSingleton::Instance().initialize(m_context.tzPkgid);
+                WidgetInstallToExtSingleton::Instance().uninstallation();
+                WidgetInstallToExtSingleton::Instance().deinitialize();
+            }
+            Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
+            {
+                // Continue uninstall even fail to remove external directory.
+                // i.e.) SD card isn't inserted or unmounted.
+                // This behavior is recommended by platform(app2sd maintainer).
+                _E("Fail to remove external directory");
+            }
+         }
+        if (APP2EXT_NOT_INSTALLED != ret) {
+            _D("Removing directory");
+            m_context.removeStarted = true;
+            DPL::Utils::Path widgetDir= m_context.installedPath;
+            Try{
+                DPL::Utils::Remove(widgetDir);
+            } Catch(DPL::Utils::Path::BaseException){
+                _E("Removing widget installation directory failed : %s", widgetDir.Fullpath().c_str());
+            }
+            DPL::Utils::Path dataDir(m_context.locations->getUserDataRootDir());
+            Try{
+                DPL::Utils::Remove(dataDir);
+            } Catch(DPL::Utils::Path::BaseException){
+                _W("%s is already removed", dataDir.Fullpath().c_str());
+            }
+        } else {
+            _E("app is not installed");
+            ThrowMsg(Exceptions::WidgetNotExist, "failed to get app location");
+        }
+    } Catch(Exception::RemoveFilesFailed) {
+        ThrowMsg(Exceptions::RemoveFileFailure, "Cann't remove directory");
+    }
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_REMOVE_WIDGETDIR,
+        "Widget INstallation Directory Removal Finished");
+}
+
+void TaskRemoveFiles::StepRemoveFinished()
+{
+    _D("StepRemoveFinished finished");
+
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_REMOVE_FINISHED,
+        "Widget remove steps Finished");
+}
+
+void TaskRemoveFiles::StartStep()
+{
+    _D("--------- <TaskRemoveFiles> : START ----------");
+}
+
+void TaskRemoveFiles::EndStep()
+{
+    _D("--------- <TaskRemoveFiles> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_remove_files.h b/src_mobile/jobs/widget_uninstall/task_remove_files.h
new file mode 100644 (file)
index 0000000..276fb24
--- /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_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_
+
+//forward declaration
+struct UninstallerContext;
+
+#include <dpl/task.h>
+#include <dpl/log/log.h>
+
+#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;
+
+  private:
+    void StepRemoveInstallationDirectory();
+    void StepRemoveFinished();
+
+    void StartStep();
+    void EndStep();
+
+  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_mobile/jobs/widget_uninstall/task_smack.cpp b/src_mobile/jobs/widget_uninstall/task_smack.cpp
new file mode 100644 (file)
index 0000000..e3471b3
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <dpl/optional_typedefs.h>
+#include <installer_log.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::StartStep);
+    AddStep(&TaskSmack::Step);
+    AddStep(&TaskSmack::EndStep);
+}
+
+void TaskSmack::Step()
+{
+    _D("------------------------> SMACK: Jobs::WidgetUninstall::TaskSmack::Step()");
+#ifdef WRT_SMACK_ENABLED
+    const char* pkgId = m_context.tzPkgid.c_str();
+    if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(pkgId)) {
+        _E("failure in revoking smack permissions");
+    }
+
+    if (PC_OPERATION_SUCCESS != perm_app_uninstall(pkgId)) {
+        _E("failure in removing smack rules file");
+    }
+#endif
+}
+
+void TaskSmack::StartStep()
+{
+    _D("--------- <TaskSmack> : START ----------");
+}
+
+void TaskSmack::EndStep()
+{
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_SMACK_DISABLE,
+        "Widget SMACK Disabled");
+
+    _D("--------- <TaskSmack> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_smack.h b/src_mobile/jobs/widget_uninstall/task_smack.h
new file mode 100644 (file)
index 0000000..c7886b9
--- /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 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();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskSmack(UninstallerContext& context);
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_UNINSTALL_TASK_SMACK_H */
diff --git a/src_mobile/jobs/widget_uninstall/task_uninstall_ospsvc.cpp b/src_mobile/jobs/widget_uninstall/task_uninstall_ospsvc.cpp
new file mode 100644 (file)
index 0000000..10cf130
--- /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.
+ */
+/**
+ * @file    task_uninstall_ospsvc.cpp
+ * @author  Soyoung Kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for widget uninstall task to uninstall ospsvc
+ */
+#include <dpl/sstream.h>
+#include <dpl/utils/bash_utils.h>
+#include <widget_uninstall/task_uninstall_ospsvc.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+const char* OSP_INSTALL_STR = "/usr/etc/package-manager/backend/tpk -uv ";
+}
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskUninstallOspsvc::TaskUninstallOspsvc(UninstallerContext& context) :
+    DPL::TaskDecl<TaskUninstallOspsvc>(this),
+    m_context(context)
+{
+    AddStep(&TaskUninstallOspsvc::StartStep);
+    AddStep(&TaskUninstallOspsvc::StepUninstallOspsvc);
+    AddStep(&TaskUninstallOspsvc::EndStep);
+}
+
+TaskUninstallOspsvc::~TaskUninstallOspsvc()
+{}
+
+void TaskUninstallOspsvc::StepUninstallOspsvc()
+{
+    _D("Step : Uninstall Osp service");
+
+    std::ostringstream commStr;
+    commStr << OSP_INSTALL_STR << BashUtils::escape_arg(m_context.tzPkgid);
+    _D("osp uninstall command : %s", commStr.str().c_str());
+
+    char readBuf[MAX_BUF_SIZE];
+    FILE *fd;
+    fd = popen(commStr.str().c_str(), "r");
+    if (NULL == fd) {
+        _E("Failed to uninstalltion osp service");
+        ThrowMsg(Exceptions::UninstallOspSvcFailed,
+                 "Error occurs during\
+                uninstall osp service");
+    }
+
+    if(fgets(readBuf, MAX_BUF_SIZE, fd) == NULL)
+    {
+        _E("Failed to uninstalltion osp service\
+                        Inability of reading file.");
+        ThrowMsg(Exceptions::UninstallOspSvcFailed,
+                "Error occurs during\
+                uninstall osp service");
+    }
+    _D("return value : %s", readBuf);
+
+    int result = atoi(readBuf);
+    if (0 != result) {
+        ThrowMsg(Exceptions::UninstallOspSvcFailed,
+                 "Error occurs during\
+                install osp service");
+    }
+
+    pclose(fd);
+
+    _D("Widget Can be uninstalled. Pkgname : %s", m_context.tzPkgid.c_str());
+    m_context.job->UpdateProgress(UninstallerContext::UNINSTALL_REMOVE_OSPSVC,
+                                  "Uninstall OSP service finished");
+}
+
+void TaskUninstallOspsvc::StartStep()
+{
+    _D("--------- <TaskUninstallOspsvc> : START ----------");
+}
+
+void TaskUninstallOspsvc::EndStep()
+{
+    _D("--------- <TaskUninstallOspsvc> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_mobile/jobs/widget_uninstall/task_uninstall_ospsvc.h b/src_mobile/jobs/widget_uninstall/task_uninstall_ospsvc.h
new file mode 100644 (file)
index 0000000..50ec347
--- /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_uninstall_ospsvc.h
+ * @author  Pawel Sikorski(p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief   Header file for widget uninstall task to uninstall ospsvc
+ */
+
+#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_UNINSTALL_OSPSVC_H
+#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_UNINSTALL_OSPSVC_H
+
+#include <dpl/task.h>
+
+struct UninstallerContext; //forward declaration
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskUninstallOspsvc :
+    public DPL::TaskDecl<TaskUninstallOspsvc>
+{
+  private:
+    //context
+    UninstallerContext& m_context;
+
+    //steps
+    void StepUninstallOspsvc();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskUninstallOspsvc(UninstallerContext& context);
+    virtual ~TaskUninstallOspsvc();
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif /* WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_UNINSTALL_OSPSVC_H */
diff --git a/src_mobile/jobs/widget_uninstall/uninstaller_context.h b/src_mobile/jobs/widget_uninstall/uninstaller_context.h
new file mode 100644 (file)
index 0000000..b6cf5bd
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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 <widget_uninstall/widget_uninstaller_struct.h>
+#include <widget_location.h>
+#include <dpl/utils/path.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+class JobWidgetUninstall;
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+struct UninstallerContext
+{
+    enum UninstallStep
+    {
+        UNINSTALL_START,
+        UNINSTALL_PRECHECK,
+        UNINSTALL_REMOVE_WIDGETDIR,
+        UNINSTALL_REMOVE_DESKTOP,
+        UNINSTALL_REMOVE_FINISHED,
+        UNINSTALL_DB_UPDATE,
+        UNINSTALL_REMOVE_OSPSVC,
+        UNINSTALL_SMACK_DISABLE,
+        UNINSTALL_END
+    };
+
+    ///< flag that indicates whether installer starts
+    //to remove files.rStruct;
+    bool removeStarted;
+    ///< flag that indicates whether installer finishes
+    //to remove files completely.
+    bool removeFinished;
+
+    DPL::Optional<WidgetLocation> locations;
+
+    UninstallStep uninstallStep;       ///< current step of installation
+    Jobs::WidgetUninstall::JobWidgetUninstall *job;
+    std::string tzAppid;
+    std::string tzPkgid;
+    bool removeAbnormal;
+    DPL::Utils::Path installedPath;
+    DPL::Utils::Path manifestFile;
+};
+
+#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_
diff --git a/src_mobile/jobs/widget_uninstall/widget_uninstall_errors.h b/src_mobile/jobs/widget_uninstall/widget_uninstall_errors.h
new file mode 100644 (file)
index 0000000..3c5970b
--- /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>
+#include <job_exception_error.h>
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetUninstall {
+namespace Exceptions {
+
+DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown)
+
+DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, AlreadyUninstalling,
+        ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, AppIsRunning, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, WidgetNotExist, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, UninstallOspSvcFailed,
+        ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PlatformAPIFailure, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, RemoveFileFailure, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, Unremovable, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, CheckMDMPolicyFailure, ErrorWidgetUninstallationFailed)
+} //namespace
+} //namespace
+} //namespace
+
+#endif /* WIDGET_UNINSTALL_ERRORS_H_ */
diff --git a/src_mobile/jobs/widget_uninstall/widget_uninstaller_struct.h b/src_mobile/jobs/widget_uninstall/widget_uninstaller_struct.h
new file mode 100644 (file)
index 0000000..3f33e4b
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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>
+#include <pkgmgr_signal_interface.h>
+#include <memory>
+
+//Widget Uninstaller typedefs
+typedef void (*UninstallerFinishedCallback)(
+    void *userParam,
+    std::string tizenId,
+    Jobs::Exceptions::Type);
+
+typedef void (*UninstallerProgressCallback)(
+    void *userParam,
+    ProgressPercent percent,
+    const ProgressDescription &description);
+
+//UninstallationStruct
+typedef Jobs::JobCallbacksBase<UninstallerFinishedCallback,
+                               UninstallerProgressCallback>
+WidgetUninstallCallbackBase;
+
+struct WidgetUninstallationStruct : public WidgetUninstallCallbackBase
+{
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgmgrInterface;
+
+    // It must be empty-constructible as a parameter of generic event
+    WidgetUninstallationStruct()
+    {}
+
+    WidgetUninstallationStruct(
+        UninstallerFinishedCallback finished,
+        UninstallerProgressCallback progress,
+        void *param,
+        std::shared_ptr<PackageManager::IPkgmgrSignal>
+        _pkgmgrInterface
+        ) :
+        WidgetUninstallCallbackBase(finished, progress, param),
+        pkgmgrInterface(_pkgmgrInterface)
+    {}
+};
+#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_
diff --git a/src_mobile/logic/installer_controller.cpp b/src_mobile/logic/installer_controller.cpp
new file mode 100644 (file)
index 0000000..d9b41d5
--- /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.
+ */
+#include "installer_controller.h"
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(Logic::InstallerController)
+
+namespace Logic {
+InstallerController::InstallerController()
+{}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::InstallWidgetEvent &event)
+{
+    std::string fileName = event.GetArg0();
+    std::string pkgId = event.GetArg1();
+    Jobs::WidgetInstall::WidgetInstallationStruct installerStruct = event.GetArg2();
+    m_installerLogic.InstallWidget(fileName, pkgId, installerStruct);
+}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::InstallPluginEvent &event)
+{
+    std::string dirName = event.GetArg0();
+    PluginInstallerStruct installerStruct = event.GetArg1();
+    m_installerLogic.InstallPlugin(dirName, installerStruct);
+}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::UninstallWidgetEvent &event)
+{
+    std::string widgetPkgName = event.GetArg0();
+    WidgetUninstallationStruct uninstallerStruct = event.GetArg1();
+    m_installerLogic.UninstallWidget(widgetPkgName, uninstallerStruct);
+}
+
+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::InitializeEvent & /*event*/)
+{
+    m_installerLogic.Initialize();
+}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::TerminateEvent & /*event*/)
+{
+    m_installerLogic.Terminate();
+}
+} //Logic
+
diff --git a/src_mobile/logic/installer_controller.h b/src_mobile/logic/installer_controller.h
new file mode 100644 (file)
index 0000000..9f04288
--- /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.
+ */
+#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_3(InstallWidgetEvent,
+            std::string,              // zipFileName
+            std::string,              // package id
+            Jobs::WidgetInstall::WidgetInstallationStruct) // 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 inicietig widget uninstallation.
+ *
+ * tizen id is used to point witch widget shuld be uninstalled
+ */
+DECLARE_GENERIC_EVENT_2(UninstallWidgetEvent,
+                        std::string,
+                        WidgetUninstallationStruct)
+
+/**
+ * @brief Event for pushing installation process forward.
+ */
+DECLARE_GENERIC_EVENT_1(NextStepEvent, Jobs::Job *)
+
+DECLARE_GENERIC_EVENT_0(InitializeEvent)
+DECLARE_GENERIC_EVENT_0(TerminateEvent)
+} // namespace InstallerEvents
+
+namespace Logic {
+/**
+ * @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::UninstallWidgetEvent,
+    InstallerControllerEvents::NextStepEvent,
+    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 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::InitializeEvent &event);
+    virtual void OnEventReceived(
+        const InstallerControllerEvents::TerminateEvent &event);
+
+  private:
+    // Embedded logic
+    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_mobile/logic/installer_logic.cpp b/src_mobile/logic/installer_logic.cpp
new file mode 100644 (file)
index 0000000..df67764
--- /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.
+ */
+#include <installer_logic.h>
+#include <installer_controller.h>
+#include <dpl/string.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-rw/feature_dao.h>
+#include <dpl/wrt-dao-rw/plugin_dao.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>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Logic {
+InstallerLogic::InstallerLogic() :
+    m_job(0),
+    m_NextHandle(0)
+{}
+
+InstallerLogic::~InstallerLogic()
+{
+        Assert(!m_job && "There are still running job");
+    //FIXME what should be done here?
+}
+
+void InstallerLogic::Initialize()
+{
+    _D("Done");
+}
+
+void InstallerLogic::Terminate()
+{
+    //TODO how to delete, if it is still running, paused and so on
+    if(m_job)
+        m_job->SetPaused(true);
+
+    _D("Done");
+}
+
+Jobs::JobHandle InstallerLogic::AddAndStartJob()
+{
+    Jobs::JobHandle handle = GetNewJobHandle();
+    m_job->SetJobHandle(handle);
+    //Start job
+    CONTROLLER_POST_EVENT(InstallerController,
+                          InstallerControllerEvents::NextStepEvent(m_job));
+
+    return handle;
+}
+
+//InstallWidget, UninstallWidget InstallPlugin method are almost the same
+// But each Job has different constructor, so creating new Job is specific
+Jobs::JobHandle InstallerLogic::InstallWidget(
+    const std::string & widgetPath,
+    const std::string & pkgId,
+    const Jobs::WidgetInstall::WidgetInstallationStruct &
+    installerStruct)
+{
+    if(m_job)
+    {
+        _E("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
+    _D("New Widget Installation:");
+
+    m_job = new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, pkgId, installerStruct);
+
+    return AddAndStartJob();
+}
+
+Jobs::JobHandle InstallerLogic::UninstallWidget(
+    const std::string & widgetPkgName,
+    const
+    WidgetUninstallationStruct &uninstallerStruct)
+{
+    if(m_job)
+    {
+        _E("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
+    _D("New Widget Uninstallation");
+
+    m_job  =
+        new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName,
+                                                      uninstallerStruct);
+
+      return AddAndStartJob();
+}
+
+Jobs::JobHandle InstallerLogic::InstallPlugin(
+    std::string const & pluginPath,     // TODO change type to PluginPath
+    const PluginInstallerStruct &
+    installerStruct)
+{
+    if(m_job)
+    {
+        _E("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
+    _D("New Plugin Installation");
+
+    // TODO Conversion to PluginPath is temporary
+    m_job =
+        new Jobs::PluginInstall::JobPluginInstall(PluginPath(pluginPath), installerStruct);
+
+    // before start install plugin, reset plugin data which is stopped
+    // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS)
+    ResetProgressPlugins();
+
+    return AddAndStartJob();
+}
+
+#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();
+
+        job->SendProgress();
+
+        if (stepSucceded) {
+            return !job->IsPaused();
+        }
+
+        if (!job->GetAbortStarted()) {
+            //job successfully finished
+
+            //send finished callback
+            job->SendFinishedSuccess();
+
+            switch (job->GetInstallationType()) {
+            case Jobs::PluginInstallation:
+                InstallWaitingPlugins();
+                break;
+            default: //because of warning
+                break;
+            }
+        } else {
+            //job abort process completed
+            job->SendFinishedFailure();
+        }
+
+        //clean job
+        delete job;
+        m_job=0;
+
+        return false;
+    } catch (Jobs::JobExceptionBase &exc) {
+        //start revert job
+        _D("Exception occured: %d. Reverting job...", exc.getParam());
+        bool hasAbortSteps = job->Abort();
+        job->SetAbortStarted(true);
+        job->SaveExceptionData(exc);
+
+        if (!hasAbortSteps) {
+            //no AbortSteps
+            job->SendFinishedFailure();
+
+            //clean job
+            delete job;
+            m_job=0;
+        }
+        return hasAbortSteps;
+    }
+}
+
+void InstallerLogic::InstallWaitingPlugins()
+{
+    PluginHandleSetPtr waitingPlugins;
+
+    waitingPlugins =
+        PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
+
+    FOREACH(it, *waitingPlugins)
+    {
+        resolvePluginDependencies(*it);
+    }
+}
+
+void InstallerLogic::ResetProgressPlugins()
+{
+    PluginHandleSetPtr progressPlugins;
+
+    progressPlugins =
+        PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_IN_PROGRESS);
+
+    FOREACH(it, *progressPlugins) {
+        FeatureHandleListPtr featureListPtr =
+            FeatureDAOReadOnly::GetFeatureHandleListForPlugin(*it);
+        FOREACH(ItFeature, *featureListPtr) {
+            FeatureDAO::UnregisterFeature(*ItFeature);
+        }
+        PluginDAO::unregisterPlugin(*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)
+        {
+            _E("Library implementing: %s NOT FOUND", (*requiredObject).c_str());
+
+            //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_mobile/logic/installer_logic.h b/src_mobile/logic/installer_logic.h
new file mode 100644 (file)
index 0000000..abe1b5c
--- /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.
+ */
+#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-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>
+#include <installer_log.h>
+
+namespace Logic {
+class InstallerLogic
+{
+    Jobs::Job* m_job;
+
+    void ResetProgressPlugins();
+    void InstallWaitingPlugins();
+    bool resolvePluginDependencies(PluginHandle handle);
+
+    Jobs::JobHandle m_NextHandle;
+    Jobs::JobHandle GetNewJobHandle()
+    {
+        return m_NextHandle++;
+    }
+    Jobs::JobHandle AddAndStartJob();
+
+  public:
+    virtual ~InstallerLogic();
+
+    void Initialize();
+
+    void Terminate();
+
+    Jobs::JobHandle InstallWidget(
+        const std::string & widgetPath,
+        const std::string & pkgId,
+        const Jobs::WidgetInstall::WidgetInstallationStruct &
+        installerStruct);
+
+    Jobs::JobHandle UninstallWidget(
+        const std::string & widgetPkgName,
+        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*/)
+    {
+        _W("Not implemented");
+        return true;
+    }
+
+  private:
+    InstallerLogic();
+
+    friend class InstallerController;
+};
+}
+
+#endif // INSTALLER_LOGIC_H
diff --git a/src_mobile/misc/feature_logic.cpp b/src_mobile/misc/feature_logic.cpp
new file mode 100644 (file)
index 0000000..818b0cd
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace {
+const DPL::String PRIVILEGE_TESTAUTOMATION =
+    L"http://tizen.org/privilege/testautomation";
+const DPL::String DEVICE_CAPABILITY_TESTAUTOMATION = L"testautomation";
+}
+FeatureLogic::FeatureLogic(const WrtDB::TizenAppId & tzAppid) :
+    m_rejected(false)
+{
+    WrtDB::WidgetDAOReadOnly widgetDao(tzAppid);
+    WidgetFeatureSet featureSet = widgetDao.getFeaturesList();
+    FOREACH(it, featureSet) {
+        _D("Feature name : %ls", it->name.c_str());
+        WrtDB::DeviceCapabilitySet dcs;
+        if (!DPL::StringCompare(it->name, PRIVILEGE_TESTAUTOMATION)) {
+            // special privilege
+            // This privilege doesn't have plugin in the target
+            // only use to special behavior
+            dcs.insert(DEVICE_CAPABILITY_TESTAUTOMATION);
+        } else {
+            // normal privilege
+            dcs = WrtDB::FeatureDAOReadOnly::GetDeviceCapability(it->name);
+        }
+        FOREACH(devCap, dcs) {
+            _D("--- dev cap  : %ls", (*devCap).c_str());
+        }
+        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;
+        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_mobile/misc/feature_logic.h b/src_mobile/misc/feature_logic.h
new file mode 100644 (file)
index 0000000..d407cb0
--- /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.
+ */
+
+#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 <memory>
+
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <wrt_common_types.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class FeatureLogic : DPL::Noncopyable
+{
+  public:
+
+    FeatureLogic(const WrtDB::TizenAppId & tzAppid);
+
+    bool isDone() const;
+
+    bool next();
+
+    void setAceResponse(bool allowed);
+
+    DPL::String getDevice() const;
+
+    bool isRejected(void) const
+    {
+        return m_rejected;
+    }
+
+    struct Feature : public WidgetFeature {
+        WrtDB::DeviceCapabilitySet devCapSet;
+        WrtDB::DeviceCapabilitySet::const_iterator currentCap;
+
+        Feature(const WidgetFeature &wf,
+                const WrtDB::DeviceCapabilitySet &set) :
+            WidgetFeature(wf)
+            , devCapSet(set)
+        {
+            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;
+            rejected = second.rejected;
+            pluginId = second.pluginId;
+            currentCap = devCapSet.find(*second.currentCap);
+        }
+    };
+
+    typedef std::list<Feature> FeatureList;
+    typedef FeatureList::const_iterator FeatureIterator;
+
+    FeatureIterator resultBegin()
+    {
+        return m_featureList.begin();
+    }
+    FeatureIterator resultEnd()
+    {
+        return m_featureList.end();
+    }
+
+  private:
+    bool isProcessable() const;
+
+    FeatureList m_featureList;
+    FeatureList::iterator m_currentFeature;
+    bool m_rejected;
+};
+
+typedef std::shared_ptr<FeatureLogic> FeatureLogicPtr;
+} // namespace WidgetInstall
+} // namespace Jobs
+
+#endif // SRC_INSTALLER_MISC_FEATURE_LOGIC
diff --git a/src_mobile/misc/libxml_utils.cpp b/src_mobile/misc/libxml_utils.cpp
new file mode 100644 (file)
index 0000000..114e95b
--- /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    libxml_utils.cpp
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ */
+
+#include "libxml_utils.h"
+
+#include <dpl/singleton_impl.h>
+#include <installer_log.h>
+
+IMPLEMENT_SINGLETON(LibxmlUtils)
+
+LibxmlUtils::LibxmlUtils() : isInitialized(false)
+{}
+
+LibxmlUtils::~LibxmlUtils()
+{
+    if (isInitialized) {
+        _D("Libxml - cleaning");
+        // Cleanup function for the XML library.
+        xmlCleanupParser();
+        //this is to debug memory for regression tests
+        xmlMemoryDump();
+    }
+}
+
+void LibxmlUtils::init()
+{
+    if (!isInitialized) {
+        LIBXML_TEST_VERSION
+            isInitialized = true;
+        _D("Libxml have been initialized");
+    }
+    _D("Libxml already initialized");
+}
+
diff --git a/src_mobile/misc/libxml_utils.h b/src_mobile/misc/libxml_utils.h
new file mode 100644 (file)
index 0000000..5354bda
--- /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    libxml_utils.h
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ */
+
+#ifndef LIBXML_UTILS_H
+#define LIBXML_UTILS_H
+
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+#include <dpl/singleton.h>
+#include <dpl/log/log.h>
+#include <dpl/string.h>
+#include <dpl/exception.h>
+
+/**
+ * @brief The LibxmlUtils class
+ *
+ * Singleton for assurence for libxml2 initialization
+ *
+ * Use: LibxmlUtils::Instance().init(); to initialize library
+ *
+ */
+class LibxmlUtils
+{
+  public:
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, Libxml2Error)
+
+    LibxmlUtils();
+    ~LibxmlUtils();
+
+    void init();
+
+  private:
+    bool isInitialized;
+
+    friend class DPL::Singleton<LibxmlUtils>;
+};
+
+typedef DPL::Singleton<LibxmlUtils> LibxmlSingleton;
+
+#endif // LIBXML_UTILS_H
diff --git a/src_mobile/misc/plugin_path.cpp b/src_mobile/misc/plugin_path.cpp
new file mode 100644 (file)
index 0000000..2b2ebdb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 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_path_builder.cpp
+ * @author  Kamil Nować (k.nowac@partner.samgsung.com)
+ * @version
+ * @brief
+ */
+
+#include <plugin_path.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dlfcn.h>
+
+using namespace DPL::Utils;
+
+PluginPath::PluginPath(const Path& fullPath) : Path(fullPath.Fullpath())
+{
+    setLibraryCombinedName(
+            WrtDB::GlobalConfig::GetPluginPrefix(),
+            WrtDB::GlobalConfig::GetPluginSuffix());
+};
+PluginPath::PluginPath(const std::string& fullPath) : Path(fullPath)
+{
+    setLibraryCombinedName(
+            WrtDB::GlobalConfig::GetPluginPrefix(),
+            WrtDB::GlobalConfig::GetPluginSuffix());
+};
+PluginPath::PluginPath(const DPL::String& fullPath) : Path(fullPath)
+{
+    setLibraryCombinedName(
+            WrtDB::GlobalConfig::GetPluginPrefix(),
+            WrtDB::GlobalConfig::GetPluginSuffix());
+};
+PluginPath::PluginPath(){}
+
+PluginPath PluginPath::getMetaFile() const
+{
+    PluginPath metaFile = *this;
+    return metaFile /= WrtDB::GlobalConfig::GetPluginMetafileName();
+}
\ No newline at end of file
diff --git a/src_mobile/misc/plugin_path.h b/src_mobile/misc/plugin_path.h
new file mode 100644 (file)
index 0000000..8ada790
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 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_path_builder.cpp
+ * @author  Kamil Nować (k.nowac@partner.samgsung.com)
+ * @version
+ * @brief
+ */
+
+#ifndef PLUGIN_PATH_H
+#define PLUGIN_PATH_H
+
+#include <string>
+#include <dpl/string.h>
+#include <dpl/utils/path.h>
+
+class PluginPath: public DPL::Utils::Path{
+private:
+    std::string m_library;
+
+public:
+    PluginPath(const DPL::Utils::Path& fullPath);
+    PluginPath(const std::string& fullPath);
+    PluginPath(const DPL::String& fullPath);
+    PluginPath();
+
+    //getMetafile() this function adds metafile to current path.
+    PluginPath getMetaFile() const;
+
+    //setLibraryCombinedName This function creates name for library by adding
+    //prefix and suffix to PluginPath object filename.
+    void setLibraryCombinedName(const std::string& prefix, const std::string& sufix)
+    {
+      this->m_library = prefix + this->Filename() + sufix;
+    }
+
+    //getLibraryName returns library name
+    const std::string& getLibraryName() const
+    {
+        return m_library;
+    }
+    //getLibraryPath returns full path to the library
+    const PluginPath getLibraryPath() const
+    {
+        return this->operator /(m_library);
+    }
+};
+
+#endif // PLUGIN_PATH_H
diff --git a/src_mobile/misc/wac_widget_id.cpp b/src_mobile/misc/wac_widget_id.cpp
new file mode 100644 (file)
index 0000000..b24679a
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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/string.h>
+
+#include <iri.h>
+#include <installer_log.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
+{
+    _D("m_schemaMatch is: %d", m_schemaMatch);
+    if (!m_schemaMatch) {
+        return false;
+    }
+
+    _D("Matching DNS identity: %s %ls", m_host.c_str(), second.c_str());
+
+    return m_host == DPL::ToUTF8String(second);
+}
+
+void WacWidgetId::parse(const char *url)
+{
+    _D("Widget id to parse: %s", url);
+
+    std::unique_ptr<iri_struct, std::function<void(iri_struct*)> >
+    iri(iri_parse(url), iri_destroy);
+
+    if (!iri.get()) {
+        _E("Error in parsing widget id.");
+        return; // m_schemaMatch == false;
+    }
+
+    std::string scheme;
+
+    if (iri.get()->scheme) {
+        scheme = iri.get()->scheme;
+    } else {
+        _W("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)) {
+        _W("Unknown scheme in widget id. %s", scheme.c_str());
+        return; // m_schemaMatch == false;
+    } else {
+        m_schemaMatch = true;
+    }
+
+    if (iri.get()->host) {
+        m_host = iri.get()->host;
+        _D("Host has been set to: %s", m_host.c_str());
+    }
+
+    // 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_mobile/misc/wac_widget_id.h b/src_mobile/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_mobile/misc/widget_install_to_external.cpp b/src_mobile/misc/widget_install_to_external.cpp
new file mode 100644 (file)
index 0000000..b0219dd
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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_install_to_external.cpp
+ * @author      Soyoung Kim (sy037.kim@smasung.com)
+ */
+#include "widget_install_to_external.h"
+
+#include <dpl/singleton_safe_impl.h>
+#include <dpl/assert.h>
+#include <installer_log.h>
+
+IMPLEMENT_SAFE_SINGLETON(WidgetInstallToExt)
+
+WidgetInstallToExt::WidgetInstallToExt() :
+    m_handle(NULL),
+    m_appId("")
+{}
+
+WidgetInstallToExt::~WidgetInstallToExt()
+{}
+
+void WidgetInstallToExt::initialize(std::string appId)
+{
+    _D("WidgetInstallToExt::initialize()");
+    m_appId = appId;
+
+    if (NULL == m_handle) {
+        m_handle = app2ext_init(APP2EXT_SD_CARD);
+        if (NULL == m_handle) {
+            ThrowMsg(Exception::ErrorInstallToExt, "initialize failed");
+        }
+    }
+}
+
+void WidgetInstallToExt::deinitialize()
+{
+    _D("WidgetInstallToExt::deinitialize()");
+    if (NULL != m_handle) {
+        if (0 < app2ext_deinit(m_handle)) {
+            ThrowMsg(Exception::ErrorInstallToExt,
+                     "app2ext deinitialize \
+                    failed");
+        }
+    }
+}
+
+void WidgetInstallToExt::preInstallation(GList *dirList, int dSize)
+{
+    _D("WidgetInstallToExt::preInstallation()");
+    Assert(m_handle);
+
+    int ret = m_handle->interface.pre_install(m_appId.c_str(), dirList, dSize);
+
+    if (APP2EXT_SUCCESS == ret) {
+        _D("App2Ext pre install success");
+    } else {
+        postInstallation(false);
+        ThrowMsg(Exception::ErrorInstallToExt, "pre-install failed");
+    }
+}
+
+void WidgetInstallToExt::postInstallation(bool status)
+{
+    _D("WidgetInstallToExt::postInstallation()");
+
+    if (NULL != m_handle) {
+        if (status) {
+            m_handle->interface.post_install(m_appId.c_str(),
+                                             APP2EXT_STATUS_SUCCESS);
+        } else {
+            m_handle->interface.post_install(m_appId.c_str(),
+                                             APP2EXT_STATUS_FAILED);
+        }
+    }
+}
+
+void WidgetInstallToExt::preUpgrade(GList *dirList, int dSize)
+{
+    _D("WidgetInstallToExt::preUpgrade()");
+    Assert(m_handle);
+
+    int ret = m_handle->interface.pre_upgrade(m_appId.c_str(), dirList, dSize);
+    if (APP2EXT_SUCCESS == ret) {
+        _D("App2Ext pre-upgrade success");
+    } else {
+        postUpgrade(false);
+        ThrowMsg(Exception::ErrorInstallToExt, "pre-upgrade failed");
+    }
+}
+
+void WidgetInstallToExt::postUpgrade(bool status)
+{
+    _D("WidgetInstallToExt::postUpgrade()");
+    if (NULL != m_handle) {
+        if (status) {
+            m_handle->interface.post_upgrade(m_appId.c_str(),
+                                             APP2EXT_STATUS_SUCCESS);
+        } else {
+            m_handle->interface.post_upgrade(m_appId.c_str(),
+                                             APP2EXT_STATUS_FAILED);
+        }
+    }
+}
+
+void WidgetInstallToExt::uninstallation()
+{
+    _D("WidgetInstallToExt::uninstallation()");
+
+    Assert(m_handle);
+
+    int ret = m_handle->interface.pre_uninstall(m_appId.c_str());
+    if (APP2EXT_SUCCESS == ret) {
+        if (APP2EXT_SUCCESS ==
+            m_handle->interface.post_uninstall(m_appId.c_str()))
+        {
+            _D("App2Ext pre-uninstall success");
+        } else {
+            ThrowMsg(Exception::ErrorInstallToExt, "post-uninstall failed");
+        }
+    } else {
+        ThrowMsg(Exception::ErrorInstallToExt, "pre-uninstall failed");
+    }
+}
+
+void WidgetInstallToExt::disable()
+{
+    _D("WidgetInstallToExt::disable()");
+    if (NULL != m_handle) {
+        int ret = m_handle->interface.disable(m_appId.c_str());
+        if (APP2EXT_SUCCESS != ret && APP2EXT_ERROR_UNMOUNT != ret) {
+            ThrowMsg(Exception::ErrorInstallToExt, "disable failed");
+        }
+    }
+}
diff --git a/src_mobile/misc/widget_install_to_external.h b/src_mobile/misc/widget_install_to_external.h
new file mode 100644 (file)
index 0000000..cc9c4df
--- /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        widget_install_to_external.h
+ * @author      Soyoung Kim (sy037.kim@smasung.com)
+ */
+#ifndef WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
+#define WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
+
+#include <string>
+#include <dpl/singleton.h>
+#include <dpl/string.h>
+#include <app2ext_interface.h>
+
+class WidgetInstallToExt
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ErrorInstallToExt)
+    };
+
+    void initialize(std::string appId);
+    void deinitialize();
+    void preInstallation(GList* dirList, int dSize);
+    void postInstallation(bool status);
+    void preUpgrade(GList* dirList, int dSize);
+    void postUpgrade(bool status);
+    void uninstallation();
+    void disable();
+
+  private:
+    app2ext_handle *m_handle;
+    std::string m_appId;
+
+    WidgetInstallToExt();
+    ~WidgetInstallToExt();
+
+    friend class DPL::Singleton<WidgetInstallToExt>;
+};
+
+typedef DPL::Singleton<WidgetInstallToExt> WidgetInstallToExtSingleton;
+
+#endif // WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
diff --git a/src_mobile/misc/widget_location.cpp b/src_mobile/misc/widget_location.cpp
new file mode 100644 (file)
index 0000000..182df80
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * 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_location.cpp
+ * @author      Iwanek Tomasz (t.iwanek@smasung.com)
+ */
+#include "widget_location.h"
+
+#include <unistd.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/assert.h>
+#include <dpl/sstream.h>
+#include <dpl/localization/localization_utils.h>
+#include <widget_install/task_commons.h>
+#include <installer_log.h>
+
+WidgetLocation::DirectoryDeletor::DirectoryDeletor(bool isReadOnly) :
+    m_dirpath(Jobs::WidgetInstall::createTempPath(isReadOnly))
+{}
+
+WidgetLocation::DirectoryDeletor::DirectoryDeletor(std::string tempPath) :
+        m_dirpath(tempPath)
+{}
+
+WidgetLocation::DirectoryDeletor::~DirectoryDeletor()
+{
+    _D("Removing widget installation temporary directory: %s", m_dirpath.c_str());
+    if (!WrtUtilRemove(m_dirpath)) {
+        _W("Fail at removing directory: %s", m_dirpath.c_str());
+    }
+}
+
+std::string WidgetLocation::DirectoryDeletor::getTempPath() const
+{
+    return m_dirpath;
+}
+
+WidgetLocation::WidgetLocation()
+{}
+
+WidgetLocation::WidgetLocation(const std::string & widgetname) :
+    m_pkgid(widgetname)
+{}
+
+WidgetLocation::~WidgetLocation()
+{}
+
+WidgetLocation::WidgetLocation(const std::string & widgetname,
+                               std::string sourcePath,
+                               WrtDB::PackagingType t,
+                               bool isReadonly,
+                               InstallMode::ExtensionType eType) :
+    m_pkgid(widgetname),
+    m_widgetSource(sourcePath),
+    m_type(t),
+    m_temp(
+        new WidgetLocation::DirectoryDeletor(isReadonly)),
+    m_extensionType(eType)
+{
+    if (isReadonly) {
+        m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+    } else {
+        m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    }
+    if (access(m_widgetSource.c_str(), F_OK) != 0) {
+        m_widgetSource = m_installedPath + "/" + m_pkgid;
+    }
+}
+
+WidgetLocation::WidgetLocation(const std::string & widgetname,
+                               std::string sourcePath,
+                               std::string dirPath,
+                               WrtDB::PackagingType t,
+                               bool isReadonly,
+                               InstallMode::ExtensionType eType) :
+    m_pkgid(widgetname),
+    m_widgetSource(sourcePath),
+    m_type(t),
+    m_temp(new WidgetLocation::DirectoryDeletor(dirPath)),
+    m_extensionType(eType)
+{
+    if (isReadonly) {
+        m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+    } else {
+        m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    }
+    if (access(m_widgetSource.c_str(), F_OK) != 0) {
+        m_widgetSource = m_installedPath + "/" + m_pkgid;
+    }
+}
+
+// TODO cache all these paths
+std::string WidgetLocation::getInstallationDir() const
+{
+    return m_installedPath;
+}
+
+std::string WidgetLocation::getPackageInstallationDir() const
+{
+    return m_installedPath + "/" + m_pkgid;
+}
+
+std::string WidgetLocation::getSourceDir() const
+{
+    return m_installedPath + "/"
+           + m_pkgid + WrtDB::GlobalConfig::GetWidgetSrcPath();
+}
+
+std::string WidgetLocation::getBinaryDir() const
+{
+    return m_installedPath + "/"
+           + m_pkgid + WrtDB::GlobalConfig::GetUserWidgetExecPath();
+}
+
+std::string WidgetLocation::getUserBinaryDir() const
+{
+    return getUserDataRootDir() + "/"
+           + WrtDB::GlobalConfig::GetUserWidgetExecPath();
+}
+
+std::string WidgetLocation::getExecFile() const
+{
+    return getBinaryDir() + "/" + m_appid;
+}
+
+std::string WidgetLocation::getBackupDir() const
+{
+    return getPackageInstallationDir() + ".backup";
+}
+
+std::string WidgetLocation::getBackupSourceDir() const
+{
+    return getBackupDir() + WrtDB::GlobalConfig::GetWidgetSrcPath();
+}
+
+std::string WidgetLocation::getBackupBinaryDir() const
+{
+    return getBackupDir() + WrtDB::GlobalConfig::GetUserWidgetExecPath();
+}
+
+std::string WidgetLocation::getBackupExecFile() const
+{
+    return getBackupBinaryDir() + "/" + m_appid;
+}
+
+std::string WidgetLocation::getBackupPrivateDir() const
+{
+    return getBackupDir() + "/" +
+        WrtDB::GlobalConfig::GetWidgetPrivateStoragePath();
+}
+
+std::string WidgetLocation::getUserDataRootDir() const
+{
+    return std::string(WrtDB::GlobalConfig::GetWidgetUserDataPath()) +
+           "/" + m_pkgid;
+}
+
+std::string WidgetLocation::getPrivateStorageDir() const
+{
+    return getUserDataRootDir() + "/" +
+           WrtDB::GlobalConfig::GetWidgetPrivateStoragePath();
+}
+
+std::string WidgetLocation::getPrivateTempStorageDir() const
+{
+    return getUserDataRootDir() + "/" +
+           WrtDB::GlobalConfig::GetWidgetPrivateTempStoragePath();
+}
+
+
+std::string WidgetLocation::getTemporaryPackageDir() const
+{
+    return m_temp->getTempPath();
+}
+
+std::string WidgetLocation::getTemporaryRootDir() const
+{
+    if (m_extensionType == InstallMode::ExtensionType::DIR) {
+        return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath();
+    }
+    return getSourceDir();
+}
+
+DPL::String WidgetLocation::getPkgId() const
+{
+    return DPL::FromUTF8String(m_pkgid);
+}
+
+std::string WidgetLocation::getInstalledIconPath() const
+{
+    return m_iconPath;
+}
+
+std::string WidgetLocation::getWidgetSource() const
+{
+    return m_widgetSource;
+}
+
+void WidgetLocation::setIconTargetFilenameForLocale(const std::string & icon)
+{
+    m_iconPath = icon;
+}
+
+void WidgetLocation::registerExternalLocation(const std::string & file)
+{
+    m_externals.push_back(file);
+}
+
+WrtDB::ExternalLocationList WidgetLocation::listExternalLocations() const
+{
+    return m_externals;
+}
+
+void WidgetLocation::registerAppid(const std::string & appid)
+{
+    m_appid = appid;
+}
+
+std::string WidgetLocation::getSharedRootDir() const
+{
+    /* TODO : add wrt-commons*/
+    return getUserDataRootDir() + "/shared";
+}
+
+std::string WidgetLocation::getSharedResourceDir() const
+{
+    return getSharedRootDir() + "/res";
+}
+
+std::string WidgetLocation::getSharedDataDir() const
+{
+    return getSharedRootDir() + "/data";
+}
+
+std::string WidgetLocation::getSharedTrustedDir() const
+{
+    return getSharedRootDir() + "/trusted";
+}
+
+std::string WidgetLocation::getBackupSharedDir() const
+{
+    return getBackupDir() + "/shared";
+}
+
+std::string WidgetLocation::getBackupSharedDataDir() const
+{
+    return getBackupSharedDir() + "/data";
+}
+
+std::string WidgetLocation::getBackupSharedTrustedDir() const
+{
+    return getBackupSharedDir() + "/trusted";
+}
+
+std::string WidgetLocation::getNPPluginsExecFile() const
+{
+    return getBinaryDir() + "/" + m_appid + ".npruntime";
+}
+
+std::string WidgetLocation::getNPPluginsDir() const
+{
+    return getSourceDir() + "/plugins";
+}
diff --git a/src_mobile/misc/widget_location.h b/src_mobile/misc/widget_location.h
new file mode 100644 (file)
index 0000000..7208170
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * 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_location.h
+ * @author      Iwanek Tomasz (t.iwanek@smasung.com)
+ */
+#ifndef WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
+#define WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
+
+#include <string>
+#include <memory>
+
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <wrt_common_types.h>
+#include <wrt_install_mode.h>
+
+/**
+ * @brief The WidgetLocation class
+ *
+ * Object that stores locations of several files/directories according
+ * to package name
+ *
+ * Current package layout (of installed package) is following:
+ *
+ * /opt/apps/[package_name]
+ *           \_____________ /data
+ *           \_____________ /share
+ *           \_____________ /bin
+ *           \_____________ /bin/[id_of_installed_package]
+ *           \_____________ /res/wgt/
+ *                               \___ config.xml
+ *                               \___ [widgets_archive_content]
+ *
+ * 1) Normal Widget
+ *  Developer provides content of res/wgt directory (package contains that
+ * directory as root).
+ *
+ * 2) For OSP Service Hybrid App is actually a bit different:
+ *  Root is OSP Service directory, WebApp content is located in [root]/res/wgt
+ *
+ * Temporary directory is directory when widget is placed at the begining
+ * of installation process. After parsing process of config.xml, destination
+ * directory is created.
+ */
+class WidgetLocation
+{
+    class DirectoryDeletor
+    {
+      public:
+        DirectoryDeletor();
+        DirectoryDeletor(std::string tempPath);
+        DirectoryDeletor(bool isPreload);
+
+        ~DirectoryDeletor();
+        std::string getTempPath() const;
+
+      private:
+        std::string m_dirpath;
+    };
+
+  public:
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, NoTemporaryPath)
+    /**
+     * @brief WidgetLocation
+     *
+     * Creates useless object. Needed by DPL::Optional
+     */
+    WidgetLocation();
+    /**
+     * @brief WidgetLocation Builds paths for widget location during
+     * uninstallation
+     *
+     * Uninstallation process needs only installed package directory.
+     *
+     * @param widgetname name of widget
+     */
+    explicit WidgetLocation(const std::string & widgetname);
+    /**
+     * @brief WidgetLocation Builds paths for widget location during
+     * installation
+     *
+     * @param widgetname name of widget
+     * @param sourcePath given source path
+     * @param t declaraced type of widget if type is needed
+     *
+     * In destruction removes temporary directory
+     */
+    WidgetLocation(const std::string & widgetname, std::string sourcePath,
+                   WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
+                   bool isReadonly = false,
+                   InstallMode::ExtensionType eType =
+                   InstallMode::ExtensionType::WGT);
+
+    WidgetLocation(const std::string & widgetname, std::string sourcePath,
+                   std::string dirPath,
+                   WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
+                   bool isReadonly = false,
+                   InstallMode::ExtensionType eType =
+                   InstallMode::ExtensionType::WGT);
+
+    ~WidgetLocation();
+
+    // Installed paths
+    std::string getInstallationDir() const; // /opt/apps or /usr/apps
+    std::string getPackageInstallationDir() const; // /opt/apps/[package]
+    std::string getSourceDir() const;  // /opt/apps/[package]/res/wgt
+    std::string getBinaryDir() const;  // /opt/apps/[package]/bin or /usr/apps/[package]/bin
+    std::string getUserBinaryDir() const;  // /opt/apps/[package]/bin
+    std::string getExecFile() const;   // /opt/apps/[package]/bin/[package]
+    std::string getBackupDir() const;  // /opt/apps/[package].backup
+    std::string getBackupSourceDir() const; // /opt/apps/[pkg].backup/res/wgt
+    std::string getBackupBinaryDir() const; // /opt/apps/[pkg].backup/bin
+    std::string getBackupExecFile() const;  // /opt/apps/[pkg].backup/bin/[pkg]
+    std::string getBackupPrivateDir() const;  // /opt/apps/[pkg].backup/data
+    std::string getUserDataRootDir() const; // /opt/usr/apps/[package]
+    std::string getPrivateStorageDir() const; // /opt/usr/apps/[package]/data
+    std::string getPrivateTempStorageDir() const; // /opt/usr/apps/[package]/tmp
+    std::string getSharedRootDir() const; // /opt/usr/apps/[package]/shared
+    std::string getSharedResourceDir() const; // /opt/usr/apps/[package]/shared/res
+    std::string getSharedDataDir() const; // /opt/usr/apps/[package]/shared/data
+    std::string getSharedTrustedDir() const; // /opt/usr/apps/[package]/shared/trusted
+    std::string getBackupSharedDir() const; // /opt/usr/apps/[package].backup/shared
+    std::string getBackupSharedDataDir() const; // /opt/usr/apps/[package].backup/shared/data
+    std::string getBackupSharedTrustedDir() const; // /opt/usr/apps/[package].backup/shared/trusted
+    std::string getNPPluginsDir() const; // /opt/usr/apps/[package]/res/wgt/plugins
+    std::string getNPPluginsExecFile() const; // /opt/usr/apps/[package]/bin/{execfile}
+
+    // Temporary paths
+    /**
+     * @brief getTemporaryRootDir
+     * @return value of root for developer's provide package (root of unpacked
+     * .wgt file)
+     */
+    std::string getTemporaryPackageDir() const;
+    /**
+     * @brief getTemporaryRootDir
+     *
+     * Value of this will differs according to type of installed widget.
+     *
+     * @return value of root for content in temporary directory to be copied
+     * into 'res/wgt'
+     */
+    std::string getTemporaryRootDir() const;
+
+    //icons
+    /**
+     * @brief setIconTargetFilenameForLocale set installed ion path according to
+     * locale
+     * @param icon path of application icon
+     */
+    void setIconTargetFilenameForLocale(const std::string &icon);
+
+    /**
+     * @brief getIconTargetFilename gets icon full path
+     * @param languageTag language tag
+     * @return value of full path
+     */
+    std::string getInstalledIconPath() const;
+
+    /**
+     * @brief getWidgetSourcePath return widget's source path given to installer
+     * @return value of source path
+     */
+    std::string getWidgetSource() const;
+    /**
+     * @brief pkgid Returns pkgid
+     * @return pkgid
+     */
+    DPL::String getPkgId() const;
+
+    //external files
+    /**
+     * @brief registerExternalFile Registers file for database registration
+     * @param file
+     *
+     * Registered file will be stored in database and removed automatically a
+     *
+     * @return
+     */
+    void registerExternalLocation(const std::string & file);
+    /**
+     * @brief listExternalFile list all file to be registered
+     */
+    WrtDB::ExternalLocationList listExternalLocations() const;
+
+    /*
+     * @brief set appid
+     */
+    void registerAppid(const std::string & appid);
+
+  private:
+    std::string m_pkgid;                        //id of package
+    std::string m_widgetSource;                   // Source widget zip
+                                                  // file/widget url
+    std::string m_appid;                        //id of app
+    std::string m_iconPath;                       //installed icon path
+    WrtDB::PackagingType m_type;
+    std::shared_ptr<DirectoryDeletor> m_temp;      //directory
+    WrtDB::ExternalLocationList m_externals;
+    std::string m_installedPath;
+    InstallMode::ExtensionType m_extensionType;
+};
+
+#endif // WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
diff --git a/src_mobile/pkg-manager/CMakeLists.txt b/src_mobile/pkg-manager/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..74fd837
--- /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.
+#
+
+SET(BACKLIB_SRCS
+    backendlib.cpp
+    ${PROJECT_SOURCE_DIR}/src_mobile/configuration_parser/widget_parser.cpp
+    ${PROJECT_SOURCE_DIR}/src_mobile/configuration_parser/parser_runner.cpp
+    ${PROJECT_SOURCE_DIR}/src_mobile/configuration_parser/ignoring_parser.cpp
+    ${PROJECT_SOURCE_DIR}/src_mobile/configuration_parser/deny_all_parser.cpp
+    ${PROJECT_SOURCE_DIR}/src_mobile/configuration_parser/libiriwrapper.cpp
+    ${PROJECT_SOURCE_DIR}/src_mobile/wrt-installer/language_subtag_rst_tree.cpp
+)
+
+PKG_CHECK_MODULES(WRT_BACKLIB_PKGS
+    dpl-efl
+    dpl-wrt-dao-ro
+    dpl-wrt-dao-rw
+    dpl-utils-efl
+    pkgmgr-installer
+    pkgmgr-types
+    pkgmgr
+    dlog
+    libpcrecpp
+    wrt-commons-i18n-dao-ro
+    REQUIRED)
+
+INCLUDE_DIRECTORIES(
+    ${WRT_BACKLIB_PKGS_INCLUDE_DIRS}
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser
+)
+
+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"
+)
+
+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_mobile/pkg-manager/DESCRIPTION b/src_mobile/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_mobile/pkg-manager/backendlib.cpp b/src_mobile/pkg-manager/backendlib.cpp
new file mode 100644 (file)
index 0000000..8367714
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * 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 <package-manager.h>
+#include <regex.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <vcore/VCore.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.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/foreach.h>
+#include <dpl/utils/folder_size.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/copy.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/zip_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/file_input.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/localization/LanguageTagsProvider.h>
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+#include <installer_log.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
+
+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);
+
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path);
+
+static void pkg_native_plugin_on_unload()
+{
+    _D("pkg_native_plugin_unload() is called");
+}
+
+static int pkg_plugin_app_is_installed(const char *pkg_name)
+{
+    const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
+    _D("pkg_plugin_app_is_installed() is called");
+
+    WrtDB::WrtDatabase::attachToThreadRO();
+
+    regex_t reg;
+    if (regcomp(&reg, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+        _D("Regcomp failed");
+    }
+
+    WrtDB::TizenAppId appid;
+
+    if (!(regexec(&reg, pkg_name,
+                    static_cast<size_t>(0), NULL, 0) == 0))
+    {
+        _E("Invalid argument : %s", pkg_name);
+        return FALSE;
+    }
+
+    Try {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTzAppId(pkgid);
+        _D("appid : %ls", appid.c_str());
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        WrtDB::WrtDatabase::detachFromThread();
+        return FALSE;
+    }
+    WrtDB::WrtDatabase::detachFromThread();
+    return TRUE;
+}
+
+static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
+                                              const char * /*option*/,
+                                              package_manager_pkg_info_t **list,
+                                              int *count)
+{
+    _D("pkg_plugin_get_installed_apps_list() is called");
+
+    package_manager_pkg_info_t *pkg_list = NULL;
+    package_manager_pkg_info_t *pkg_last = NULL;
+
+    WrtDB::WrtDatabase::attachToThreadRO();
+    TizenAppIdList tizenAppidList = WidgetDAOReadOnly::getTizenAppidList();
+    *count = 0;
+
+    FOREACH(iterator, tizenAppidList) {
+        package_manager_pkg_info_t *pkg_info =
+            static_cast<package_manager_pkg_info_t*>
+            (malloc(sizeof(package_manager_pkg_info_t)));
+
+        if (NULL == pkg_list) {
+            pkg_list = pkg_info;
+            pkg_last = pkg_info;
+        } else {
+            pkg_last->next = pkg_info;
+        }
+
+        TizenAppId tzAppid = *iterator;
+        WidgetDAOReadOnly widget(tzAppid);
+        strncpy(pkg_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
+        snprintf(pkg_info->pkg_name, PKG_NAME_STRING_LEN_MAX, "%s",
+                 DPL::ToUTF8String(tzAppid).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 - 1);
+        }
+
+        (*count)++;
+        pkg_last = pkg_info;
+    }
+    *list = pkg_list;
+    WrtDB::WrtDatabase::detachFromThread();
+
+    return TRUE;
+}
+
+static int pkg_plugin_get_app_detail_info(
+    const char *pkg_name,
+    package_manager_pkg_detail_info_t *
+    pkg_detail_info)
+{
+    _D("pkg_plugin_get_app_detail_info() is called");
+
+    WrtDB::WrtDatabase::attachToThreadRO();
+
+    WrtDB::TizenAppId appid;
+    Try {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTzAppId(pkgid);
+        _D("appid : %ls", appid.c_str());
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        WrtDB::WrtDatabase::detachFromThread();
+        return FALSE;
+    }
+
+    WidgetDAOReadOnly widget(appid);
+
+    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 - 1);
+    }
+    snprintf(pkg_detail_info->pkgid, PKG_NAME_STRING_LEN_MAX, "%s",
+             pkg_name);
+    snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%s",
+             DPL::ToUTF8String(appid).c_str());
+    WidgetLocalizedInfo localizedInfo;
+
+    if (locale.IsNull()) {
+        _D("locale 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 - 1);
+    }
+    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 - 1);
+
+    std::string min_version = DPL::ToUTF8String((*widget.getMinimumWacVersion()));
+
+    strncpy(pkg_detail_info->min_platform_version, min_version.c_str(),
+            PKG_VERSION_STRING_LEN_MAX - 1);
+
+    /* 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);
+
+    WrtDB::WrtDatabase::detachFromThread();
+    return TRUE;
+}
+
+int getConfigParserData(const std::string &widgetPath, ConfigParserData& configInfo)
+{
+    const char* CONFIG_XML = "config.xml";
+    const char* WITH_OSP_XML = "res/wgt/config.xml";
+
+    Try {
+        ParserRunner parser;
+
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        // Open config.xml file
+        Try {
+            configFile.reset(zipFile->OpenFile(CONFIG_XML));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
+        }
+
+        // Extract config
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        parser.Parse(&buffer,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(configInfo,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        _E("Failed to open widget package");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        _E("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::CopyFailed)
+    {
+        _E("Failed to extract config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::FileInput::Exception::OpenFailed)
+    {
+        _E("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        _E("Failed to parse config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::SeekFileFailed)
+    {
+        _E("Failed to seek widget archive - corrupted package?");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+char* getIconInfo(const std::string &widgetPath,
+        const std::string &icon_name, int &icon_size)
+{
+    Try {
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> iconFile;
+
+        Try {
+            iconFile.reset(zipFile->OpenFile(icon_name));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            _D("This web app is hybrid web app");
+            std::string hybrid_icon = "res/wgt/" + icon_name;
+            iconFile.reset(zipFile->OpenFile(hybrid_icon));
+        }
+
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(iconFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        icon_size = buffer.Size();
+        char *getBuffer = (char*) calloc(1, (sizeof(char) * icon_size) + 1);
+        buffer.Flatten(getBuffer, buffer.Size());
+        return getBuffer;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        _D("Failed to open widget package");
+        return NULL;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        _D("Not found icon file %s", icon_name.c_str());
+        return NULL;
+    }
+}
+
+char* getIconForLocale(const std::string& bp, const std::string& tag,
+                                     const std::string& icon, int & size)
+{
+    std::string iconPath;
+    if (!tag.empty()) {
+        iconPath += std::string("locales/") + tag;
+    }
+    if (!iconPath.empty()) {
+        iconPath += "/";
+    }
+
+    iconPath += icon;
+    return getIconInfo(bp, iconPath, size);
+}
+
+char* getIcon(const std::string & basepath, const WrtDB::ConfigParserData & config, int & size)
+{
+    const std::list<std::string> defaultIcons{ "icon.svg", "icon.ico", "icon.png", "icon.gif", "icon.jpg" };
+    LanguageTags tagsList =
+        LanguageTagsProviderSingleton::Instance().getLanguageTags();
+
+    char * result = NULL;
+
+    //for each locale tag - searching for icon presence and returning raw data
+    //first found is best as locale tags are ordered
+    FOREACH(tag, tagsList)
+    {
+        FOREACH(icon, config.iconsList)
+        {
+            std::string src = DPL::ToUTF8String(icon->src);
+            result = getIconForLocale(basepath, DPL::ToUTF8String(*tag), src, size);
+            if(result) {
+                return result;
+            }
+        }
+        FOREACH(i, defaultIcons)
+        {
+            result = getIconForLocale(basepath, DPL::ToUTF8String(*tag), *i, size);
+            if(result) {
+                return result;
+            }
+        }
+    }
+    return NULL;
+}
+
+int getWidgetDetailInfoFromPackage(const char* pkgPath,
+        package_manager_pkg_detail_info_t* pkg_detail_info)
+{
+    const std::string widget_path(pkgPath);
+    ConfigParserData configInfo;
+
+    if (FALSE == getConfigParserData(widget_path, configInfo)) {
+        return FALSE;
+    }
+
+    strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
+    if (!configInfo.tizenPkgId.IsNull()) {
+        strncpy(pkg_detail_info->pkgid,
+                DPL::ToUTF8String(*configInfo.tizenPkgId).c_str(), PKG_TYPE_STRING_LEN_MAX - 1);
+    }
+    if (!configInfo.tizenAppId.IsNull()) {
+        strncpy(pkg_detail_info->pkg_name,
+                DPL::ToUTF8String(*configInfo.tizenAppId).c_str(),
+                PKG_NAME_STRING_LEN_MAX - 1);
+    }
+    if (!configInfo.version.IsNull()) {
+        strncpy(pkg_detail_info->version,
+                DPL::ToUTF8String(*configInfo.version).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    DPL::Optional<DPL::String> name;
+    DPL::Optional<DPL::String> desc;
+
+    LanguageTags tags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
+
+    auto toLowerCase = [](const DPL::String & r)
+    {
+        DPL::String result;
+        std::transform(r.begin(), r.end(), std::inserter(result, result.begin()), ::tolower);
+        return result;
+    };
+
+    if (!!configInfo.defaultlocale)
+    {
+        Locale & dl = *configInfo.defaultlocale;
+        configInfo.defaultlocale = toLowerCase(dl);
+    }
+
+    bool found = false;
+    FOREACH(tag, tags)
+    {
+        *tag = toLowerCase(*tag);
+        FOREACH(localizedData, configInfo.localizedDataSet)
+        {
+            Locale i = localizedData->first;
+            i = toLowerCase(i);
+
+            if (!!configInfo.defaultlocale && *configInfo.defaultlocale == i)
+            {
+                name = localizedData->second.name;
+                desc = localizedData->second.description;
+            }
+            if (*tag == i)
+            {
+                name = localizedData->second.name;
+                desc = localizedData->second.description;
+                found = true;
+                break;
+            }
+        }
+        if(found) break;
+    }
+
+    if( !name.IsNull()) {
+        strncpy(pkg_detail_info->label, DPL::ToUTF8String(*name).c_str(),
+                PKG_LABEL_STRING_LEN_MAX - 1);
+    }
+
+    if (!desc.IsNull()) {
+        strncpy(pkg_detail_info->pkg_description,
+                DPL::ToUTF8String(*desc).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    if (!configInfo.tizenMinVersionRequired.IsNull()) {
+        strncpy(pkg_detail_info->min_platform_version,
+                DPL::ToUTF8String(*configInfo.tizenMinVersionRequired).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    if (!configInfo.authorName.IsNull()) {
+        strncpy(pkg_detail_info->author,
+                DPL::ToUTF8String(*configInfo.authorName).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+
+    pkg_detail_info->privilege_list = NULL;
+    FOREACH(it, configInfo.featuresList) {
+        std::string featureInfo =  DPL::ToUTF8String(it->name);
+        _D("privilege : %s", featureInfo.c_str());
+        int length = featureInfo.size();
+        char *privilege = (char*) calloc(1, (sizeof(char) * (length + 1)));
+        snprintf(privilege, length + 1, "%s", featureInfo.c_str());
+        pkg_detail_info->privilege_list =
+            g_list_append(pkg_detail_info->privilege_list, privilege);
+    }
+
+    char* icon_buf = getIcon(widget_path, configInfo, pkg_detail_info->icon_size);
+
+    if (icon_buf) {
+        _D("icon size : %d", pkg_detail_info->icon_size);
+        pkg_detail_info->icon_buf = icon_buf;
+    } else {
+        _D("No icon");
+        pkg_detail_info->icon_size = 0;
+        pkg_detail_info->icon_buf = NULL;
+    }
+
+    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)
+{
+    _D("pkg_plugin_get_app_detail_info_from_package() is called");
+    return getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+}
+
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path)
+{
+    _D("pkgmgr_client_check_pkginfo_from_file() is called");
+    package_manager_pkg_detail_info_t *pkg_detail_info;
+    pkg_detail_info = (package_manager_pkg_detail_info_t*)malloc(
+            sizeof(package_manager_pkg_detail_info_t));
+    int ret = getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+    if (FALSE == ret) {
+        _E("Failed to get package detail info ");
+        return NULL;
+    }
+    return reinterpret_cast<pkgmgr_info*>(pkg_detail_info);
+}
+
+__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_mobile/pkg-manager/pkgmgr_signal.cpp b/src_mobile/pkg-manager/pkgmgr_signal.cpp
new file mode 100644 (file)
index 0000000..140e224
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Yunchan Cho (yunchan.cho@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+
+#include <dpl/lexical_cast.h>
+
+#include <pkgmgr_installer.h>
+#include <pkg-manager/pkgmgr_signal.h>
+#include <installer_log.h>
+
+namespace {
+// package type sent in every signal
+const char PKGMGR_WEBAPP_TYPE[] = "wgt";
+
+// notification about opoeration start
+const char PKGMGR_START_KEY[] = "start";
+
+// value for new installation
+const char PKGMGR_START_INSTALL[] = "install";
+
+// value for update installation
+const char PKGMGR_START_UPDATE[] = "update";
+
+// value for uninstallation
+const char PKGMGR_START_UNINSTALL[] = "uninstall";
+
+// notification about progress of installation with percentage number
+const char PKGMGR_PROGRESS_KEY[] = "install_percent";
+
+// notification about icon path for installation frontend
+const char PKGMGR_ICON_PATH[] = "icon_path";
+
+// notification about error before end with given error code
+// (currently, same as backend exit status)
+const char PKGMGR_ERROR[] = "error";
+
+// notification about end of installation with status
+const char PKGMGR_END_KEY[] = "end";
+
+// success value of end of installation
+const char PKGMGR_END_SUCCESS[] = "ok";
+
+// failure value of end of installation
+const char PKGMGR_END_FAILURE[] = "fail";
+}
+
+namespace PackageManager {
+PkgmgrSignal::PkgmgrSignal() :
+    m_initialized(false),
+    m_handle(NULL),
+    m_reqType(RequestType::UNSUPPORTED)
+{}
+
+PkgmgrSignal::~PkgmgrSignal()
+{}
+
+bool PkgmgrSignal::initialize(int argc, char* argv[])
+{
+    if (m_handle) {
+        _D("Release already allocated pkgmgr handle");
+        pkgmgr_installer_free(m_handle);
+        m_handle = NULL;
+    }
+
+    m_handle = pkgmgr_installer_new();
+    if (!m_handle) {
+        _E("Fail to get pkgmgr installer handle");
+        return false;
+    }
+
+    // set information from pkgmgr
+    if (!pkgmgr_installer_receive_request(
+            m_handle, argc, argv))
+    {
+        auto pkgmgrtype = pkgmgr_installer_get_request_type(m_handle);
+        switch(pkgmgrtype)
+        {
+            case PKGMGR_REQ_INSTALL:
+                m_reqType = RequestType::INSTALL;
+                break;
+            case PKGMGR_REQ_UNINSTALL:
+                m_reqType = RequestType::UNINSTALL;
+                break;
+            case PKGMGR_REQ_REINSTALL:
+                m_reqType = RequestType::REINSTALL;
+                break;
+            default:
+                m_reqType = RequestType::UNSUPPORTED;
+                break;
+        }
+
+        if (m_reqType == RequestType::UNSUPPORTED)
+        {
+            _E("Fail to get request type of pkgmgr");
+            pkgmgr_installer_free(m_handle);
+            m_handle = NULL;
+            return false;
+        }
+        const char *callerId = pkgmgr_installer_get_caller_pkgid(m_handle);
+        if(callerId)
+            m_callerId = callerId;
+
+    } else {
+        _E("Fail to get information of pkgmgr's request");
+        pkgmgr_installer_free(m_handle);
+        m_handle = NULL;
+        return false;
+    }
+
+    m_type = PKGMGR_WEBAPP_TYPE;
+    m_initialized = true;
+    return true;
+}
+
+bool PkgmgrSignal::deinitialize()
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+        return false;
+    }
+
+    pkgmgr_installer_free(m_handle);
+    m_handle = NULL;
+    m_initialized = false;
+    return true;
+}
+
+bool PkgmgrSignal::setPkgname(const std::string& name)
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+        return false;
+    }
+
+    if (name.empty()) {
+        _E("name is empty");
+        return false;
+    }
+
+    m_pkgname = name;
+    _D("Success to set tizen package name: %s", m_pkgname.c_str());
+
+    return true;
+}
+
+bool PkgmgrSignal::startJob(Jobs::InstallationType type)
+{
+    switch(type)
+    {
+        case Jobs::InstallationType::NewInstallation:
+            sendSignal(PKGMGR_START_KEY, PKGMGR_START_INSTALL);
+            break;
+        case Jobs::InstallationType::UpdateInstallation:
+            sendSignal(PKGMGR_START_KEY, PKGMGR_START_UPDATE);
+            break;
+        case Jobs::InstallationType::Uninstallation:
+            sendSignal(PKGMGR_START_KEY, PKGMGR_START_UNINSTALL);
+            break;
+        default:
+            _E("Trying to send unknown installation type to pkgmgr");
+            return false;
+    }
+    return true;
+}
+
+bool PkgmgrSignal::endJob(Jobs::Exceptions::Type ecode)
+{
+    if(ecode == Jobs::Exceptions::Type::Success)
+    {
+        return sendSignal(PKGMGR_END_KEY, PKGMGR_END_SUCCESS);
+    }
+    else
+    {
+        sendSignal(PKGMGR_ERROR, DPL::lexical_cast<std::string>(ecode));
+        return sendSignal(PKGMGR_END_KEY, PKGMGR_END_FAILURE);
+    }
+}
+
+bool PkgmgrSignal::sendProgress(int percent)
+{
+    return sendSignal(PKGMGR_PROGRESS_KEY, DPL::lexical_cast<std::string>(percent));
+}
+
+bool PkgmgrSignal::sendIconPath(const std::string & iconpath)
+{
+    return sendSignal(PKGMGR_ICON_PATH, iconpath);
+}
+
+bool PkgmgrSignal::sendSignal(const std::string& key,
+                              const std::string& value) const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+        return false;
+    }
+
+    if (key.empty() || value.empty()) {
+        _D("key or value is empty");
+        return false;
+    }
+
+    if (m_handle == NULL || m_type.empty()) {
+        _E("Some data of PkgmgrSignal is empty");
+        return false;
+    }
+
+    // send pkgmgr signal
+    if (pkgmgr_installer_send_signal(
+            m_handle, m_type.c_str(), m_pkgname.c_str(),
+            key.c_str(), value.c_str()))
+    {
+        _E("Fail to send pkgmgr signal");
+        return false;
+    }
+
+    _D("Success to send pkgmgr signal: %s - %s", key.c_str(), value.c_str());
+    return true;
+}
+
+std::string PkgmgrSignal::getPkgname() const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+    }
+
+    return m_pkgname;
+}
+
+PkgmgrSignal::RequestType PkgmgrSignal::getRequestedType() const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+    }
+
+    return m_reqType;
+}
+
+std::string PkgmgrSignal::getCallerId() const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+    }
+
+    return m_callerId;
+}
+} // PackageManager
diff --git a/src_mobile/pkg-manager/pkgmgr_signal.h b/src_mobile/pkg-manager/pkgmgr_signal.h
new file mode 100644 (file)
index 0000000..abd756b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Yunchan Cho (yunchan.cho@samsung.com)
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     0.2
+ * @brief
+ */
+
+#ifndef WRT_PKGMGR_SIGNAL_H_
+#define WRT_PKGMGR_SIGNAL_H_
+
+#include <pkg-manager/pkgmgr_signal_interface.h>
+
+struct pkgmgr_installer;
+
+namespace PackageManager {
+
+class PkgmgrSignal : public IPkgmgrSignal
+{
+public:
+    enum class RequestType
+    {
+        UNSUPPORTED,
+        INSTALL,
+        UNINSTALL,
+        REINSTALL
+    };
+
+    bool initialize(int argc, char* argv[]);
+    bool deinitialize();
+    bool setPkgname(const std::string& name);
+    std::string getPkgname() const;
+    RequestType getRequestedType() const;
+    std::string getCallerId() const;
+
+    bool startJob(Jobs::InstallationType type);
+    bool endJob(Jobs::Exceptions::Type ecode);
+    bool sendProgress(int percent);
+    bool sendIconPath(const std::string & iconpath);
+
+    PkgmgrSignal();
+    virtual ~PkgmgrSignal();
+
+protected:
+    bool sendSignal(const std::string& key, const std::string& value) const;
+
+private:
+    bool m_initialized;
+    pkgmgr_installer* m_handle;
+    std::string m_type;
+    std::string m_pkgname;
+    RequestType m_reqType;
+    std::string m_callerId;
+};
+} // PackageManager
+
+#endif // WRT_PKGMGR_SIGNAL_H_
+
diff --git a/src_mobile/pkg-manager/pkgmgr_signal_dummy.h b/src_mobile/pkg-manager/pkgmgr_signal_dummy.h
new file mode 100644 (file)
index 0000000..42b0aa4
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     0.1
+ * @brief       Dummy version of PkgmgrSignal.
+ */
+
+#ifndef WRT_PKGMGR_SIGNAL_DUMMY_H_
+#define WRT_PKGMGR_SIGNAL_DUMMY_H_
+
+#include <pkg-manager/pkgmgr_signal_interface.h>
+
+#include <dpl/availability.h>
+
+namespace PackageManager {
+class PkgmgrSignalDummy : public IPkgmgrSignal
+{
+  public:
+    PkgmgrSignalDummy()
+    {}
+
+    virtual ~PkgmgrSignalDummy()
+    {}
+
+    bool setPkgname(const std::string& /*name*/)
+    {
+        return false;
+    }
+
+    std::string getPkgname() const
+    {
+        return "";
+    }
+
+    std::string getCallerId() const
+    {
+        return "";
+    }
+
+    bool startJob(Jobs::InstallationType type DPL_UNUSED)
+    {
+        return false;
+    }
+
+    bool endJob(Jobs::Exceptions::Type ecode DPL_UNUSED)
+    {
+        return false;
+    }
+
+    bool sendProgress(int percent DPL_UNUSED)
+    {
+        return false;
+    }
+
+    bool sendIconPath(const std::string & iconpath DPL_UNUSED)
+    {
+        return false;
+    }
+};
+} // PkgmgrSignalDummy
+
+#endif // WRT_PKGMGR_SIGNAL_DUMMY_H_
diff --git a/src_mobile/pkg-manager/pkgmgr_signal_interface.h b/src_mobile/pkg-manager/pkgmgr_signal_interface.h
new file mode 100644 (file)
index 0000000..1e38a17
--- /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.
+ */
+/*
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     0.1
+ * @brief       Interface for PkgmgrSignal.
+ */
+
+#ifndef WRT_PKGMGR_SIGNAL_INTERFACE_H_
+#define WRT_PKGMGR_SIGNAL_INTERFACE_H_
+
+#include <string>
+
+#include <job_types.h>
+#include <job_exception_error.h>
+
+namespace PackageManager {
+class IPkgmgrSignal
+{
+  public:
+    virtual bool setPkgname(const std::string& name) = 0;
+    virtual std::string getPkgname() const = 0;
+    virtual std::string getCallerId() const = 0;
+
+    virtual bool startJob(Jobs::InstallationType type) = 0;
+    virtual bool endJob(Jobs::Exceptions::Type ecode) = 0;
+    virtual bool sendProgress(int percent) = 0;
+    virtual bool sendIconPath(const std::string & iconpath) = 0;
+    virtual ~IPkgmgrSignal(){}
+};
+} // IPkgmgrSignal
+
+#endif // WRT_PKGMGR_SIGNAL_INTERFACE_H_
diff --git a/src_mobile/wrt-installer/CMakeLists.txt b/src_mobile/wrt-installer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e22fdc5
--- /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   Lukasz Wrzosek (l.wrzosek@samsung.com)
+# @version     1.0
+#
+
+SET(WRT_INSTALLER_DIR
+    ${INSTALLER_SRC_DIR}/wrt-installer
+    )
+
+SET(PKG_MANAGER_DIR
+    ${INSTALLER_SRC_DIR}/pkg-manager
+    )
+
+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_MANAGER_DIR}/pkgmgr_signal.cpp
+)
+
+PKG_CHECK_MODULES(WRT_INSTALLER_DEPS
+    pkgmgr-installer
+    libpcrecpp
+    pkgmgr-info
+    pkgmgr
+    security-install
+    wrt-commons-i18n-dao-ro
+    REQUIRED)
+
+INCLUDE_DIRECTORIES(
+    ${PKG_MANAGER_DIR}
+    ${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(${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"
+    BUILD_WITH_INSTALL_RPATH ON
+    INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_INSTALLER} DESTINATION bin)
diff --git a/src_mobile/wrt-installer/installer_callbacks_translate.cpp b/src_mobile/wrt-installer/installer_callbacks_translate.cpp
new file mode 100644 (file)
index 0000000..ca52dd6
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * 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/assert.h>
+#include <installer_log.h>
+
+namespace InstallerCallbacksTranslate {
+
+// callback for finished install
+void installFinishedCallback(void *userParam,
+                             std::string tizenId,
+                             Jobs::Exceptions::Type status)
+{
+    Assert(userParam != NULL);
+
+    StatusCallbackStruct *apiStr =
+        static_cast<StatusCallbackStruct*>(userParam);
+
+    if (apiStr->status_callback) {
+        // Translate error
+        WrtErrStatus errorStatus;
+
+        switch (status) {
+        case Jobs::Exceptions::Success:
+            errorStatus = WRT_SUCCESS;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageLowerVersion:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageExecutableNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_EXCUTABLE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorManifestNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorManifestInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_MANIFEST_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorConfigNotFound:
+            errorStatus = WRT_INSTALLER_CONFIG_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorConfigInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_CONFIG_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorSignatureNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorSignatureInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_SIGNATURE_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorSignatureVerificationFailed:
+            errorStatus = WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorRootCertificateNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorCertificationInvaid:
+            errorStatus = WRT_INSTALLER_ERROR_CERTIFICATION_INVAID;
+            break;
+
+        case
+            Jobs::Exceptions::ErrorCertificateChainVerificationFailed:
+            errorStatus =
+            WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorCertificateExpired:
+            errorStatus = WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED;
+            break;
+
+        case Jobs::Exceptions::ErrorInvalidPrivilege:
+            errorStatus = WRT_INSTALLER_ERROR_INVALID_PRIVILEGE;
+            break;
+
+        case Jobs::Exceptions::ErrorPrivilegeLevelViolation:
+            errorStatus = WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION;
+            break;
+
+        case Jobs::Exceptions::ErrorMenuIconNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorFatalError:
+            errorStatus = WRT_INSTALLER_ERROR_FATAL_ERROR;
+            break;
+
+        case Jobs::Exceptions::ErrorOutOfStorage:
+            errorStatus = WRT_INSTALLER_ERROR_OUT_OF_STORAGE;
+            break;
+
+        case Jobs::Exceptions::ErrorOutOfMemory:
+            errorStatus = WRT_INSTALLER_ERROR_OUT_OF_MEMORY;
+            break;
+
+        case Jobs::Exceptions::ErrorArgumentInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_ARGUMENT_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageAlreadyInstalled:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED;
+            break;
+
+        case Jobs::Exceptions::ErrorAceCheckFailed:
+            errorStatus = WRT_INSTALLER_ERROR_ACE_CHECK_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorManifestCreateFailed:
+            errorStatus = WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorEncryptionFailed:
+            errorStatus = WRT_INSTALLER_ERROR_ENCRYPTION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorInstallOspServcie:
+            errorStatus = WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE;
+            break;
+
+        default:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+        }
+
+        // Callback
+        apiStr->status_callback(tizenId, errorStatus, apiStr->userdata);
+    } else {
+        _D("installFinishedCallback: No callback");
+    }
+}
+
+// callback for finished install
+void uninstallFinishedCallback(void *userParam,
+                               std::string tizenId,
+                               Jobs::Exceptions::Type status)
+{
+    Assert(userParam != NULL);
+
+    StatusCallbackStruct *apiStr =
+        static_cast<StatusCallbackStruct*>(userParam);
+
+    if (apiStr->status_callback) {
+        // Translate error
+        WrtErrStatus errorStatus;
+
+        switch (status) {
+        case Jobs::Exceptions::Success:
+            errorStatus = WRT_SUCCESS;
+            break;
+
+        case Jobs::Exceptions::ErrorWidgetUninstallationFailed:
+            errorStatus = WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorUnknown:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+
+        default:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+        }
+
+        // Callback
+        apiStr->status_callback(tizenId, errorStatus, apiStr->userdata);
+    } else {
+        _D("uninstallFinishedCallback: No callback");
+    }
+}
+
+void pluginInstallFinishedCallback(void *userParam,
+                                   Jobs::Exceptions::Type status)
+{
+    Assert(userParam);
+
+    PluginStatusCallbackStruct *apiStr =
+        static_cast<PluginStatusCallbackStruct*>(userParam);
+
+    if (apiStr->statusCallback) {
+        // Translate error
+        WrtErrStatus errorStatus;
+
+        switch (status) {
+        case Jobs::Exceptions::Success:
+            errorStatus = WRT_SUCCESS;
+            break;
+        case Jobs::Exceptions::ErrorPluginInstallationFailed:
+            errorStatus = WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED;
+            break;
+        default:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+        }
+
+        apiStr->statusCallback(errorStatus, apiStr->userdata);
+    } else {
+        _D("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
+        _D("Entered %2.0f%% %s", percent, description.c_str());
+        apiStr->progress_callback(static_cast<float>(percent),
+                                  description.c_str(),
+                                  apiStr->userdata);
+    } else {
+        _D("installProgressCallback: ignoring NULL callback pointer");
+    }
+}
+} //namespace
+
diff --git a/src_mobile/wrt-installer/installer_callbacks_translate.h b/src_mobile/wrt-installer/installer_callbacks_translate.h
new file mode 100644 (file)
index 0000000..5322078
--- /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    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>
+#include <string>
+
+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 installFinishedCallback(void *userParam,
+                             std::string tizenId,
+                             Jobs::Exceptions::Type status);
+
+void uninstallFinishedCallback(void *userParam,
+                               std::string tizenId,
+                               Jobs::Exceptions::Type status);
+
+void pluginInstallFinishedCallback(void *userParam,
+                                   Jobs::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_mobile/wrt-installer/installer_main_thread.cpp b/src_mobile/wrt-installer/installer_main_thread.cpp
new file mode 100644 (file)
index 0000000..b398d3c
--- /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       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 <vcore/VCore.h>
+#include <dpl/singleton_impl.h>
+#include <dpl/assert.h>
+#include <installer_controller.h>
+#include <ace_api_install.h>
+
+IMPLEMENT_SINGLETON(InstallerMainThread)
+
+using namespace WrtDB;
+
+InstallerMainThread::InstallerMainThread() : m_attached(false) {}
+
+InstallerMainThread::~InstallerMainThread()
+{
+    Assert(!m_attached);
+}
+
+void InstallerMainThread::AttachDatabases()
+{
+    Assert(!m_attached);
+    // Attach databases
+    ValidationCore::AttachToThreadRW();
+    ace_return_t ret = ace_install_initialize();
+    Assert(ACE_OK == ret); // to be changed to exception in the future
+    WrtDB::WrtDatabase::attachToThreadRW();
+    m_attached = true;
+}
+
+void InstallerMainThread::DetachDatabases()
+{
+    Assert(m_attached);
+    m_attached = false;
+    // Detach databases
+    ValidationCore::DetachFromThread();
+    ace_return_t ret = ace_install_shutdown();
+    Assert(ACE_OK == ret); // to be changed to exception in the future
+    WrtDB::WrtDatabase::detachFromThread();
+}
+
+void InstallerMainThread::TouchArchitecture()
+{
+    // Touch controller
+    Logic::InstallerControllerSingleton::Instance().Touch();
+}
+
+void InstallerMainThread::TouchArchitectureOnlyInstaller()
+{
+    // Touch controller
+    Logic::InstallerControllerSingleton::Instance().Touch();
+}
diff --git a/src_mobile/wrt-installer/installer_main_thread.h b/src_mobile/wrt-installer/installer_main_thread.h
new file mode 100644 (file)
index 0000000..bd70b16
--- /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       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_mobile/wrt-installer/language_subtag_rst_tree.cpp b/src_mobile/wrt-installer/language_subtag_rst_tree.cpp
new file mode 100644 (file)
index 0000000..a2bfaf5
--- /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    language_subtag_rst_tree.cpp
+ * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ */
+#include <language_subtag_rst_tree.h>
+#include <dpl/db/orm.h>
+#include <dpl/string.h>
+#include <dpl/scope_guard.h>
+#include <wrt-commons/i18n-dao-ro/i18n_dao_read_only.h>
+#include <wrt-commons/i18n-dao-ro/i18n_database.h>
+#include <iterator>
+#include <vector>
+#include <ctype.h>
+#include <dpl/singleton_impl.h>
+#include <installer_log.h>
+
+IMPLEMENT_SINGLETON(LanguageSubtagRstTree)
+
+namespace I18nDAOReadOnly = I18n::DB::I18nDAOReadOnly;
+
+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;
+    }
+
+    I18n::DB::Interface::attachDatabaseRO();
+    DPL_SCOPE_EXIT()
+    {
+        I18n::DB::Interface::detachDatabase();
+    };
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_LANGUAGE))
+    {
+        ++token;
+    }
+    else
+    {
+        return false;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG))
+    {
+        ++token;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT))
+    {
+        ++token;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION))
+    {
+        ++token;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    while (token != parts.end())
+    {
+        if (I18nDAOReadOnly::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) { \
+        _D("Good validate status for lang: %s", str); \
+    } else { \
+        _E("Wrong validate status for lang: %s, should be %d", str, 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_mobile/wrt-installer/language_subtag_rst_tree.h b/src_mobile/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_mobile/wrt-installer/option_parser.cpp b/src_mobile/wrt-installer/option_parser.cpp
new file mode 100644 (file)
index 0000000..982d86f
--- /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    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_mobile/wrt-installer/option_parser.h b/src_mobile/wrt-installer/option_parser.h
new file mode 100644 (file)
index 0000000..7fa8c3a
--- /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_mobile/wrt-installer/plugin_utils.cpp b/src_mobile/wrt-installer/plugin_utils.cpp
new file mode 100644 (file)
index 0000000..cabda19
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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 <unistd.h>
+#include "plugin_utils.h"
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <sys/file.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace PluginUtils {
+const char* PLUGIN_INSTALL_LOCK_FILE = "/tmp/.wrt_plugin_install_lock";
+
+static int s_plugin_install_lock_fd = -1;
+
+bool lockPluginInstallation(bool isPreload)
+{
+    if (isPreload) {
+        fprintf(stderr, "Skip create lock file.. \n");
+        return true;
+    }
+
+    int ret = 0;
+
+    _D("Try to lock for plugins installation.");
+
+    s_plugin_install_lock_fd =
+        open(PLUGIN_INSTALL_LOCK_FILE, O_RDONLY | O_CREAT, 0666);
+
+    if (s_plugin_install_lock_fd == -1) {
+        _E("Lock file open failed!");
+
+        return false;
+    }
+
+    ret = flock(s_plugin_install_lock_fd, LOCK_EX); //lock with waiting
+
+    if (ret == -1) {
+        _E("Lock failed!");
+
+        close(s_plugin_install_lock_fd);
+        s_plugin_install_lock_fd = -1;
+
+        return false;
+    }
+
+    return true;
+}
+
+bool unlockPluginInstallation(bool isPreload)
+{
+    _D("Unlock for plugins installation.");
+    if (isPreload) {
+        fprintf(stderr, "Skip plugin unlock.. \n");
+        return true;
+    }
+
+    if (s_plugin_install_lock_fd != -1) {
+        int ret = 0;
+
+        ret = flock(s_plugin_install_lock_fd, LOCK_UN); //unlock
+
+        if (ret == -1) {
+            _E("Unlock failed!");
+        }
+
+        close(s_plugin_install_lock_fd);
+        s_plugin_install_lock_fd = -1;
+
+        return true;
+    } else {
+        _E("Lock file was not created!");
+    }
+
+    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:
+        _W("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_mobile/wrt-installer/plugin_utils.h b/src_mobile/wrt-installer/plugin_utils.h
new file mode 100644 (file)
index 0000000..8659f20
--- /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    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 isPreload);
+bool unlockPluginInstallation(bool isPreload);
+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_mobile/wrt-installer/wrt-installer.cpp b/src_mobile/wrt-installer/wrt-installer.cpp
new file mode 100644 (file)
index 0000000..61a0c2a
--- /dev/null
@@ -0,0 +1,1160 @@
+/*
+ * 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 <map>
+#include <cstring>
+#include <cstdlib>
+#include <dirent.h>
+#include <sys/resource.h>
+
+#include <dpl/optional_typedefs.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/zip_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/copy.h>
+#include <dpl/errno_string.h>
+#include <dpl/utils/wrt_global_settings.h>
+#include <dpl/utils/wrt_utility.h>
+#include <parser_runner.h>
+#include <widget_parser.h>
+#include <root_parser.h>
+#include <pkgmgr-info.h>
+
+#include <Elementary.h>
+
+#include <pkg-manager/pkgmgr_signal_dummy.h>
+#include <pkg-manager/pkgmgr_signal.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace { // anonymous
+const char * const PKGMGR_INSTALL_MSG = "Install widget";
+const char * const PKGMGR_UNINSTALL_MSG = "Uninstall widget";
+
+const char * const CONFIG_XML = "config.xml";
+const char * const HYBRID_CONFIG_XML = "res/wgt/config.xml";
+
+const unsigned int NOFILE_CNT_FOR_INSTALLER = 9999;
+
+struct free_deleter
+{
+    void operator()(void* x)
+    {
+        free(x);
+    }
+};
+
+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_initialized(false),
+    m_numPluginsToInstall(0),
+    m_totalPlugins(0),
+    m_returnStatus(-1),
+    m_installByPkgmgr(false),
+    m_startupPluginInstallation(false)
+{
+    Touch();
+    _D("App Created");
+}
+
+WrtInstaller::~WrtInstaller()
+{
+    _D("App Finished");
+}
+
+int WrtInstaller::getReturnStatus() const
+{
+    return m_returnStatus;
+}
+
+void WrtInstaller::OnStop()
+{
+    _D("Stopping Dummy Client");
+}
+
+void WrtInstaller::OnCreate()
+{
+    _D("Creating DummyClient");
+    showArguments();
+
+    AddStep(&WrtInstaller::initStep);
+
+    std::string arg = m_argv[0];
+
+    pkgmgrSignalInterface =
+        std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
+            std::shared_ptr<PackageManager::PkgmgrSignalDummy>(
+                new PackageManager::PkgmgrSignalDummy()
+                )
+            );
+
+    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
+            return showHelpAndQuit();
+        } else if (arg == "-p" || arg == "--install-plugins") {
+            if (m_argc != 2) {
+                return showHelpAndQuit();
+            }
+
+            if (!m_startupPluginInstallation) {
+                AddStep(&WrtInstaller::installPluginsStep);
+            } else {
+                _D("Plugin installation alredy started");
+            }
+        } else if (arg == "-i" || arg == "--install") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+
+            struct stat info;
+            if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) {
+                _D("Installing package directly from directory");
+                m_installMode.extension = InstallMode::ExtensionType::DIR;
+            } else {
+                _D("Installing from regular location");
+                m_installMode.extension = InstallMode::ExtensionType::WGT;
+            }
+            m_packagePath = m_argv[2];
+
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-ip" || arg == "--install-preload") {
+            _D("Install preload web app");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_packagePath = m_argv[2];
+            m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
+            m_installMode.rootPath = InstallMode::RootPath::RO;
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-ipw" || arg == "--install-preload-writable") {
+            _D("Install preload web application to writable storage");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_packagePath = m_argv[2];
+            m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
+            m_installMode.rootPath = InstallMode::RootPath::RW;
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-c" || arg == "--csc-update") {
+            // "path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true"
+            _D("Install & uninstall by csc configuration");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_installMode.installTime = InstallMode::InstallTime::CSC;
+            std::string configuration = m_argv[2];
+            m_CSCconfigurationMap = parseCSCConfiguration(configuration);
+
+            CSCConfiguration::dataMap::iterator it;
+            it = m_CSCconfigurationMap.find(CSCConfiguration::KEY_OP);
+            if (it == m_CSCconfigurationMap.end()) {
+                return showHelpAndQuit();
+            }
+
+            if (it->second == CSCConfiguration::VALUE_INSTALL) {
+                _D("operation = %s", it->second.c_str());
+                m_installMode.extension = InstallMode::ExtensionType::WGT;
+                it = m_CSCconfigurationMap.find(CSCConfiguration::KEY_PATH);
+                if (it == m_CSCconfigurationMap.end()) {
+                    return showHelpAndQuit();
+                }
+                m_packagePath = it->second;
+
+                it = m_CSCconfigurationMap.find(
+                        CSCConfiguration::KEY_REMOVABLE);
+                if (it == m_CSCconfigurationMap.end()) {
+                    return showHelpAndQuit();
+                }
+
+                m_installMode.removable =
+                    (it->second.compare(CSCConfiguration::VALUE_FALSE) == 0)
+                    ? false : true;
+
+                AddStep(&WrtInstaller::installStep);
+                _D("path      = %s", m_packagePath.c_str());
+            } else if (it->second == CSCConfiguration::VALUE_UNINSTALL) {
+                _D("operation = %s", it->second.c_str());
+                // uninstall command isn't confirmed yet
+                it = m_CSCconfigurationMap.find(CSCConfiguration::KEY_PATH);
+                if (it == m_CSCconfigurationMap.end()) {
+                    return showHelpAndQuit();
+                }
+                m_packagePath = it->second;
+                AddStep(&WrtInstaller::unistallWgtFileStep);
+                _D("operation = uninstall");
+                _D("path      = %s", m_packagePath.c_str());
+            } else {
+                _E("Unknown operation : %s", it->second.c_str());
+                _D("operation = %s", it->second.c_str());
+                return showHelpAndQuit();
+            }
+        } else if (arg == "-un" || arg == "--uninstall-name") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_name = m_argv[2];
+            AddStep(&WrtInstaller::uninstallPkgNameStep);
+        } else if (arg == "-up" || arg == "--uninstall-packagepath") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_packagePath = m_argv[2];
+            AddStep(&WrtInstaller::unistallWgtFileStep);
+        } else if (arg == "-r" || arg == "--reinstall") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            _D("Installing package directly from directory");
+            m_installMode.command = InstallMode::Command::REINSTALL;
+            m_installMode.extension = InstallMode::ExtensionType::DIR;
+            m_packagePath = m_argv[2];
+            AddStep(&WrtInstaller::installStep);
+        } else {
+            return showHelpAndQuit();
+        }
+    } else if (arg.find("backend") != std::string::npos) {
+        using namespace PackageManager;
+        m_installByPkgmgr = true;
+
+        auto pkgmgrSignal = std::shared_ptr<PackageManager::PkgmgrSignal>(
+                new PackageManager::PkgmgrSignal()
+                );
+
+        pkgmgrSignal->initialize(m_argc, m_argv);
+
+        PackageManager::PkgmgrSignal::RequestType reqType = pkgmgrSignal->getRequestedType();
+
+        pkgmgrSignalInterface =
+            std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
+                pkgmgrSignal);
+        switch (reqType) {
+        case PackageManager::PkgmgrSignal::RequestType::INSTALL:
+            m_packagePath = m_argv[4];
+            if (6 < m_argc) {
+                m_name = std::string(m_argv[6]);
+            }
+
+            struct stat info;
+            if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) {
+                _D("Installing package directly from directory");
+                m_installMode.extension = InstallMode::ExtensionType::DIR;
+            } else {
+                _D("Installing from regular location");
+                m_installMode.extension = InstallMode::ExtensionType::WGT;
+            }
+            AddStep(&WrtInstaller::installStep);
+            break;
+        case PackageManager::PkgmgrSignal::RequestType::UNINSTALL:
+            {
+                m_name = m_argv[4];
+                pkgmgrinfo_pkginfo_h handle = NULL;
+                bool system_app = false; // system app is preloaded and unremovable.
+                bool update = false;
+
+                if (0 == pkgmgrinfo_pkginfo_get_pkginfo(m_name.c_str(), &handle)) {
+                    if (0 > pkgmgrinfo_pkginfo_is_system(handle, &system_app)) {
+                        _E("Can't get package information : %s", m_name.c_str());
+                    }
+                    if (0 > pkgmgrinfo_pkginfo_is_update(handle, &update)) {
+                        _E("Can't get package information about update : %s", m_name.c_str());
+                    }
+                }
+
+                _D("system app : %d", system_app);
+                _D("update : %d", update);
+
+                if (system_app && update) {
+                    AddStep(&WrtInstaller::removeUpdateStep);
+                } else {
+                    AddStep(&WrtInstaller::uninstallPkgNameStep);
+                }
+                break;
+            }
+        case PackageManager::PkgmgrSignal::RequestType::REINSTALL:
+            m_packagePath = m_argv[4];
+            m_installMode.command = InstallMode::Command::REINSTALL;
+            m_installMode.extension = InstallMode::ExtensionType::DIR;
+            AddStep(&WrtInstaller::installStep);
+            break;
+        default:
+            _D("Not available type");
+            break;
+        }
+    }
+
+    AddStep(&WrtInstaller::shutdownStep);
+    DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
+        PostEvent(
+        WRTInstallerNS::NextStepEvent());
+}
+
+void WrtInstaller::OnReset(bundle* /*b*/)
+{
+    _D("OnReset");
+}
+
+void WrtInstaller::OnTerminate()
+{
+    _D("Wrt Shutdown now");
+    PluginUtils::unlockPluginInstallation(
+        m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
+    if (m_initialized) {
+        wrt_installer_shutdown();
+    }
+}
+
+void WrtInstaller::showHelpAndQuit()
+{
+    printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/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 or update widget package for given path\n"
+           "  -c,    --csc-update                           "
+           "install or uninstall by CSC configuration \n"
+           "  -un,   --uninstall-name                       "
+           "uninstall widget for given package name\n"
+           "  -up,   --uninstall-packagepath                "
+           "uninstall widget for given package file path\n"
+           "  -r,    --reinstall                            "
+           "reinstall web application\n"
+           "\n");
+
+    Quit();
+}
+
+void WrtInstaller::showArguments()
+{
+    fprintf(stderr,
+            "===========================================================\n");
+    fprintf(stderr, "# wrt-installer #\n");
+    fprintf(stderr, "# argc [%d]\n", m_argc);
+    for (int i = 0; i < m_argc; i++) {
+        fprintf(stderr, "# argv[%d] = [%s]\n", i, m_argv[i]);
+    }
+    fprintf(stderr,
+            "===========================================================\n");
+    // for dlog
+    _D("===========================================================");
+    _D("# wrt-installer #");
+    _D("# argc %d", m_argc);
+    for (int i = 0; i < m_argc; i++) {
+        _D("# argv[%d] = %s", i, m_argv[i]);
+    }
+    _D("===========================================================");
+
+}
+
+void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/)
+{
+    _D("Quiting");
+
+    if (m_initialized) {
+        _D("Wrt Shutdown now");
+        SwitchToStep(&WrtInstaller::shutdownStep);
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
+            PostEvent(
+            WRTInstallerNS::NextStepEvent());
+    } else {
+        _D("Quiting application");
+        return Quit();
+    }
+}
+
+void WrtInstaller::OnEventReceived(
+    const WRTInstallerNS::NextStepEvent& /*event*/)
+{
+    _D("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);
+    } else {
+        delete privateData;
+    }
+}
+
+void WrtInstaller::initStep()
+{
+    wrt_installer_init(this, staticWrtInitCallback);
+}
+
+void WrtInstaller::installStep()
+{
+    _D("Installing widget ...");
+    std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
+                                                        m_packagePath.c_str()));
+
+    wrt_install_widget(packagePath ? packagePath.get() : m_packagePath.c_str(),
+                       m_name.c_str(), this, &staticWrtStatusCallback,
+                       (m_installByPkgmgr)
+                       ? &staticWrtInstallProgressCallback : NULL,
+                       m_installMode,
+                       pkgmgrSignalInterface);
+}
+
+void WrtInstaller::installPluginsStep()
+{
+    _D("Installing plugins ...");
+    fprintf(stderr, "Installing plugins ...\n");
+
+    if (m_startupPluginInstallation) {
+        _D("Plugin installation started because new plugin package found");
+    } else if (!PluginUtils::lockPluginInstallation(
+        m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
+    {
+        _E("Failed to open plugin installation lock file"
+                 " Plugins are currently installed by other process");
+        staticWrtPluginInstallationCallback(WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
+                                            this);
+        return;
+    }
+
+    std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
+
+    DIR *dir;
+    dir = opendir(PLUGIN_PATH.c_str());
+
+    if (!dir) {
+        return;
+    }
+
+    _D("Plugin DIRECTORY IS %s", PLUGIN_PATH.c_str());
+
+    std::list<std::string> pluginsPaths;
+    struct dirent libdir;
+    struct dirent *result;
+    int return_code;
+    errno = 0;
+    for (return_code = readdir_r(dir, &libdir, &result);
+            result != NULL && return_code == 0;
+            return_code = readdir_r(dir, &libdir, &result))
+    {
+        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) {
+            _E("Failed to open file %s", path.c_str());
+            continue;
+        }
+
+        if (!S_ISDIR(tmp.st_mode)) {
+            _E("Not a directory %s", path.c_str());
+            continue;
+        }
+
+        pluginsPaths.push_back(path);
+    }
+
+    if (return_code != 0 || errno != 0) {
+        _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
+    }
+
+    //set nb of plugins to install
+    //this value indicate how many callbacks are expected
+    m_numPluginsToInstall = pluginsPaths.size();
+    _D("Plugins to install: %d", m_numPluginsToInstall);
+    m_pluginsPaths = pluginsPaths;
+
+    m_totalPlugins = m_numPluginsToInstall;
+    DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
+        ::PostEvent(WRTInstallerNS::InstallPluginEvent());
+
+    if (-1 == TEMP_FAILURE_RETRY(closedir(dir))) {
+        _E("Failed to close dir: %s with error: %s", PLUGIN_PATH.c_str(), DPL::GetErrnoString().c_str());
+    }
+}
+
+void WrtInstaller::uninstallPkgNameStep()
+{
+    _D("Uninstalling widget ...");
+    _D("Package name : %s", m_name.c_str());
+
+    wrt_uninstall_widget(m_name.c_str(), this,
+            &staticWrtStatusCallback,
+            (m_installByPkgmgr)
+            ? &staticWrtUninstallProgressCallback : NULL,
+            pkgmgrSignalInterface);
+}
+
+void WrtInstaller::removeUpdateStep()
+{
+    _D("This web app need to initialize preload app");
+    _D("Package name : %s", m_name.c_str());
+
+    wrt_uninstall_widget(m_name.c_str(), this,
+            &staticWrtInitializeToPreloadCallback,
+            (m_installByPkgmgr)
+            ? &staticWrtUninstallProgressCallback : NULL,
+            pkgmgrSignalInterface);
+
+}
+
+void WrtInstaller::unistallWgtFileStep()
+{
+    _D("Uninstalling widget ...");
+
+    Try {
+        // Parse config
+        ParserRunner parser;
+        ConfigParserData configInfo;
+
+        // Open zip file
+        std::unique_ptr<DPL::ZipInput> zipFile(
+            new DPL::ZipInput(m_packagePath));
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        Try {
+            // Open config.xml file
+            configFile.reset(zipFile->OpenFile(CONFIG_XML));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            // Open config.xml file for hybrid
+            configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
+        }
+
+        // Extract config
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        parser.Parse(&buffer,
+                     ElementParserPtr(
+                         new RootParser<WidgetParser>(configInfo,
+                                                      DPL::FromUTF32String(
+                                                          L"widget"))));
+
+        DPL::OptionalString pkgId = configInfo.tizenPkgId;
+        if (!pkgId.IsNull()) {
+            _D("Pkgid from packagePath : %ls", (*pkgId).c_str());
+            wrt_uninstall_widget(
+                DPL::ToUTF8String(*pkgId).c_str(), this, &staticWrtStatusCallback,
+                !m_installByPkgmgr ? &staticWrtUninstallProgressCallback
+                : NULL,
+                pkgmgrSignalInterface);
+        } else {
+            _E("Fail to uninstalling widget... ");
+            m_returnStatus = -1;
+            DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+                PostEvent(
+                WRTInstallerNS::QuitEvent());
+        }
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        _E("Failed to open widget package");
+        printf("failed: widget package does not exist\n");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        printf("failed: widget config file does not exist\n");
+        _E("Failed to open config.xml file");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        printf("failed: can not parse config file\n");
+        _E("Failed to parse config.xml file");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+}
+
+void WrtInstaller::shutdownStep()
+{
+    _D("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) {
+        _D("Init succesfull");
+        This->m_initialized = true;
+        This->m_returnStatus = 0;
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    } else {
+        _E("Init unsuccesfull");
+        This->m_returnStatus = -1;
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+}
+
+void WrtInstaller::staticWrtInitializeToPreloadCallback(std::string tizenId, WrtErrStatus
+        status, void* userdata)
+{
+    WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    Assert(This);
+
+    std::string printMsg = "uninstallation";
+
+    if (WRT_SUCCESS != status) {
+        // Failure
+        _E("Step failed");
+        This->m_returnStatus = 1;
+
+        This->showErrorMsg(status, tizenId, printMsg);
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
+            ::PostEvent(WRTInstallerNS::QuitEvent());
+    } else {
+        InstallMode mode;
+        mode.extension = InstallMode::ExtensionType::DIR;
+        mode.installTime = InstallMode::InstallTime::PRELOAD;
+        mode.rootPath = InstallMode::RootPath::RO;
+        std::string packagePath =
+            std::string(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath()) + "/" +
+            This->m_name;
+
+        wrt_install_widget(packagePath.c_str(), tizenId.c_str(),
+                This, &staticWrtInitPreloadStatusCallback,
+                NULL,
+                mode,
+                This->pkgmgrSignalInterface);
+    }
+}
+
+void WrtInstaller::staticWrtInitPreloadStatusCallback(std::string tizenId,
+                                           WrtErrStatus status,
+                                           void* userdata)
+{
+    WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    Assert(This);
+
+    std::string printMsg = "initialization";
+
+    if (WRT_SUCCESS != status) {
+        // Failure
+        _E("Step failed");
+        This->m_returnStatus = status;
+
+        This->showErrorMsg(status, tizenId, printMsg);
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
+            ::PostEvent(WRTInstallerNS::QuitEvent());
+    } else {
+        fprintf(stderr,
+                "## wrt-installer : %s %s was successful.\n",
+                tizenId.c_str(),
+                printMsg.c_str());
+        _D("Status succesfull");
+        This->m_returnStatus = 0;
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
+                                                     NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    }
+}
+
+void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
+                                           WrtErrStatus status,
+                                           void* userdata)
+{
+    WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    Assert(This);
+
+    Step current = This->GetCurrentStep();
+    std::string printMsg;
+
+    if (current == &WrtInstaller::installStep) {
+        printMsg = "installation";
+    } else if (current == &WrtInstaller::uninstallPkgNameStep ||
+               current == &WrtInstaller::unistallWgtFileStep)
+    {
+        printMsg = "uninstallation";
+    }
+
+    if (WRT_SUCCESS != status) {
+        // Failure
+        _E("Step failed");
+        This->m_returnStatus = status;
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
+            ::PostEvent(WRTInstallerNS::QuitEvent());
+
+        This->showErrorMsg(status, tizenId, printMsg);
+    } else {
+        fprintf(stderr,
+                "## wrt-installer : %s %s was successful.\n",
+                tizenId.c_str(),
+                printMsg.c_str());
+        _D("Status succesfull");
+        This->m_returnStatus = 0;
+
+        if (This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD &&
+                !This->m_packagePath.empty())
+        {
+            _D("This widget is preloaded so it will be removed : %s", This->m_packagePath.c_str());
+            if (!WrtUtilRemove(This->m_packagePath)) {
+                _E("Failed to remove %s", This->m_packagePath.c_str());
+            }
+        }
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
+                                                     NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    }
+}
+
+void WrtInstaller::showErrorMsg(WrtErrStatus status, std::string tizenId,
+        std::string printMsg)
+{
+    switch (status) {
+        case WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - widget package does not exist\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PACKAGE_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - invalid widget package\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - given"
+                    " version is lower than existing version\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - manifest"
+                    " file doesn't find in package.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MANIFEST_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid manifestx.xml\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_CONFIG_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "config.xml does not exist\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CONFIG_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid config.xml\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "signature doesn't exist in package.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_SIGNATURE_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid signature.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "signature verification failed.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "root certificate could not find.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CERTIFICATION_INVAID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid certification.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "certificate chain verification failed.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "certificate expired.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_INVALID_PRIVILEGE:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid privilege\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "privilege level violation\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "menu icon could not find\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_FATAL_ERROR:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "fatal error\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "out of storage\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "out of memory\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ARGUMENT_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid argument\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "package already installed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "ace check failure\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "to create manifest failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "encryption of resource failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "installation of osp service failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "widget uninstallation failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+
+        case WRT_INSTALLER_ERROR_UNKNOWN:
+            fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        default:
+            break;
+    }
+
+}
+
+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--;
+    _D("Plugins to install: %d", This->m_numPluginsToInstall);
+
+    if (This->m_numPluginsToInstall < 1) {
+        _D("All plugins installation completed");
+        fprintf(stderr, "All plugins installation completed.\n");
+
+        //remove installation request
+        if (!PluginUtils::removeInstallationRequiredFlag()) {
+            _D("Failed to remove file initializing plugin installation");
+        }
+
+        //remove lock file
+        if (!PluginUtils::unlockPluginInstallation(
+            This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
+        {
+            _D("Failed to remove installation lock");
+        }
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    } else {
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
+                                                     InstallPluginEvent>::
+            PostEvent(
+            WRTInstallerNS::InstallPluginEvent());
+    }
+
+    if (WRT_SUCCESS == status) {
+        This->m_returnStatus = 0;
+        fprintf(stderr,
+                "## wrt-installer : plugin installation successfull [%s]\n",
+                path.c_str());
+        _D("One plugin Installation succesfull: %s", path.c_str());
+        return;
+    }
+
+    // Failure
+    _W("One of the plugins installation failed!: %s", path.c_str());
+
+    switch (status) {
+    case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
+        _E("failed: plugin installation failed\n");
+        break;
+
+    case WRT_INSTALLER_ERROR_UNKNOWN:
+        _E("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);
+
+    _D("Plugin Installation: %s progress: %2.0f description: %s", path.c_str(), percent, description);
+}
+
+void WrtInstaller::staticWrtInstallProgressCallback(float percent,
+                                                    const char* description,
+                                                    void* /*userdata*/)
+{
+    //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    _D(" progress: %2.0f description: %s", percent, description);
+}
+void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
+                                                      const char* description,
+                                                      void* /*userdata*/)
+{
+    //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    _D(" progress: %2.0f description: %s", percent, description);
+}
+
+void WrtInstaller::installNewPlugins()
+{
+    _D("Install new plugins");
+
+    if (!PluginUtils::lockPluginInstallation(
+        m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
+    {
+        _D("Lock NOT created");
+        return;
+    }
+
+    if (!PluginUtils::checkPluginInstallationRequired()) {
+        _D("Plugin installation not required");
+        PluginUtils::unlockPluginInstallation(
+            m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
+        return;
+    }
+
+    m_startupPluginInstallation = true;
+    AddStep(&WrtInstaller::installPluginsStep);
+}
+
+CSCConfiguration::dataMap WrtInstaller::parseCSCConfiguration(
+    std::string str)
+{
+    // path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true
+    // parsing CSC configuration string
+    _D("parseConfiguration");
+    CSCConfiguration::dataMap result;
+
+    if (str.empty()) {
+        _D("Input argument is empty");
+        return result;
+    }
+
+    char* buf = strdup(str.c_str());
+    const char* ptr = strtok(buf,":");
+    while (ptr != NULL) {
+        std::string string = ptr;
+        ptr = strtok (NULL, ":");
+        size_t pos = string.find('=');
+        if (pos == std::string::npos) {
+            continue;
+        }
+        result.insert(
+            CSCConfiguration::dataPair(string.substr(0, pos),
+                                       string.substr(pos+1)));
+    }
+    free(buf);
+    return result;
+}
+
+int main(int argc, char *argv[])
+{
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_INSTALLER");
+
+        // 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);
+
+        // Check and re-set the file open limitation
+        struct rlimit rlim;
+        if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
+            _D("RLIMIT_NOFILE sft(%d)", rlim.rlim_cur);
+            _D("RLIMIT_NOFILE hrd(%d)", rlim.rlim_max);
+
+            if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
+                rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
+                rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
+                if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
+                    _E("setrlimit is fail!!");
+                }
+            }
+        } else {
+            _E("getrlimit is fail!!");
+        }
+
+        WrtInstaller app(argc, argv);
+        int ret = app.Exec();
+        _D("App returned: %d", ret);
+        ret = app.getReturnStatus();
+        _D("WrtInstaller returned: %d", ret);
+        return ret;
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+}
diff --git a/src_mobile/wrt-installer/wrt-installer.h b/src_mobile/wrt-installer/wrt-installer.h
new file mode 100644 (file)
index 0000000..e8feefb
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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_INSTALLER_H
+#define WRT_INSTALLER_H
+
+#include <dpl/application.h>
+#include <dpl/generic_event.h>
+#include <dpl/event/controller.h>
+#include <dpl/task.h>
+#include <dpl/string.h>
+#include <string>
+#include <map>
+#include <wrt_installer_api.h>
+#include <wrt_install_mode.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);
+namespace CSCConfiguration {
+typedef std::map<std::string, std::string> dataMap;
+typedef std::pair<std::string, std::string> dataPair;
+const char* const KEY_OP = "op";
+const char* const KEY_PATH = "path";
+const char* const KEY_REMOVABLE = "removable";
+const char* const VALUE_INSTALL = "install";
+const char* const VALUE_UNINSTALL = "uninstall";
+const char* const VALUE_TRUE = "true";
+const char* const VALUE_FALSE = "false";
+}
+
+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;
+
+  protected:
+    virtual void OnStop();
+    virtual void OnCreate();
+    virtual void OnReset(bundle *b);
+    virtual void OnTerminate();
+
+  private:
+    void         showHelpAndQuit();
+    void         showArguments();
+
+    // 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 installPluginsStep();
+    void uninstallPkgNameStep();
+    void unistallWgtFileStep();
+    void removeUpdateStep();
+    void shutdownStep();
+
+    // Static callbacks
+    static void staticWrtInitCallback(WrtErrStatus status,
+                                      void* userdata);
+    static void staticWrtStatusCallback(std::string tizenId,
+                                        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 staticWrtInitializeToPreloadCallback(std::string tizenId,
+                                        WrtErrStatus status,
+                                        void* userdata);
+
+    static void staticWrtInitPreloadStatusCallback(std::string tizenId,
+                                        WrtErrStatus status,
+                                        void* userdata);
+
+    void installNewPlugins();
+    CSCConfiguration::dataMap parseCSCConfiguration(std::string str);
+    void showErrorMsg(WrtErrStatus status, std::string tizenId, std::string
+            printMsg);
+
+    // Private data
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgmgrSignalInterface;
+    InstallMode m_installMode;
+    std::string m_packagePath;
+    std::string m_name;
+    bool m_initialized;
+    size_t m_numPluginsToInstall;
+    size_t m_totalPlugins;
+    int m_returnStatus;
+    bool m_installByPkgmgr;
+    bool m_startupPluginInstallation;
+    CSCConfiguration::dataMap m_CSCconfigurationMap;
+
+    typedef std::list<std::string> PluginPathList;
+    DPL::Optional<PluginPathList> m_pluginsPaths;
+};
+#endif // WRT_INSTALLER_H
diff --git a/src_mobile/wrt-installer/wrt_installer_api.cpp b/src_mobile/wrt-installer/wrt_installer_api.cpp
new file mode 100644 (file)
index 0000000..ba1ee19
--- /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_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/assert.h>
+#include <dpl/semaphore.h>
+#include <dpl/sstream.h>
+#include <dpl/errno_string.h>
+#include <libxml/parser.h>
+
+#include <wrt_installer_api.h>
+#include <installer_callbacks_translate.h>
+#include <installer_controller.h>
+#include <language_subtag_rst_tree.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/utils/widget_version.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>
+#include <wrt_install_mode.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+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;
+    }
+    _E("Cannot access directory [ %s ]", path.c_str());
+    return false;
+}
+
+static bool checkPaths()
+{
+    bool if_ok = true;
+
+    if_ok &= (checkPath(cutOffFileName(GlobalConfig::GetWrtDatabaseFilePath())));
+    if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
+    if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
+    if_ok &= (checkPath(GlobalConfig::GetUserPreloadedWidgetPath()));
+
+    return if_ok;
+}
+
+void wrt_installer_init(void *userdata,
+                                  WrtInstallerInitCallback callback)
+{
+    try {
+        _D("[WRT-API] INITIALIZING WRT INSTALLER...");
+        _D("[WRT-API] BUILD: %s", __TIMESTAMP__);
+
+        // Touch InstallerController Singleton
+        InstallerMainThreadSingleton::Instance().TouchArchitecture();
+
+        // Check paths
+        if (!checkPaths()) {
+            if (callback) {
+                callback(WRT_INSTALLER_ERROR_FATAL_ERROR, userdata);
+            }
+            return;
+        }
+
+        // Initialize ValidationCore - this must be done before AttachDatabases
+        ValidationCore::VCoreInit(
+            std::string(GlobalConfig::GetFingerprintListFile()),
+            std::string(GlobalConfig::GetFingerprintListSchema()),
+            std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
+
+        InstallerMainThreadSingleton::Instance().AttachDatabases();
+
+        _D("Prepare libxml2 to work in multithreaded program.");
+        xmlInitParser();
+
+        // Initialize Language Subtag registry
+        LanguageSubtagRstTreeSingleton::Instance().Initialize();
+
+        // Installer init
+        CONTROLLER_POST_SYNC_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::
+                InitializeEvent());
+
+        if (callback) {
+            _D("[WRT-API] WRT INSTALLER INITIALIZATION CALLBACK");
+            callback(WRT_SUCCESS, userdata);
+        }
+    } catch (const DPL::Exception& ex) {
+        _E("Internal Error during Init:");
+        DPL::Exception::DisplayKnownException(ex);
+        if (callback) {
+            callback(WRT_INSTALLER_ERROR_FATAL_ERROR, userdata);
+            return;
+        }
+    }
+    return;
+}
+
+void wrt_installer_shutdown()
+{
+    try {
+        _D("[WRT-API] DEINITIALIZING WRT INSTALLER...");
+
+        // Installer termination
+        CONTROLLER_POST_SYNC_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::
+                TerminateEvent());
+
+        InstallerMainThreadSingleton::Instance().DetachDatabases();
+
+        // This must be done after DetachDatabase
+        ValidationCore::VCoreDeinit();
+
+        // Global deinit check
+        _D("Cleanup libxml2 global values.");
+        xmlCleanupParser();
+    } catch (const DPL::Exception& ex) {
+        _E("Internal Error during Shutdown:");
+        DPL::Exception::DisplayKnownException(ex);
+    }
+}
+
+void wrt_install_widget(
+    const char *path,
+    const char *tzPkgId,
+    void* userdata,
+    WrtInstallerStatusCallback status_cb,
+    WrtProgressCallback progress_cb,
+    InstallMode installMode,
+    std::shared_ptr<PackageManager::
+                        IPkgmgrSignal> pkgmgrInterface
+    )
+{
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        if (InstallMode::InstallTime::PRELOAD == installMode.installTime) {
+            DPL::Log::OldStyleLogProvider *oldStyleProvider =
+                new DPL::Log::OldStyleLogProvider(false, false, false, true,
+                        false, true);
+            DPL::Log::LogSystemSingleton::Instance().AddProvider(oldStyleProvider);
+        }
+
+        _D("[WRT-API] INSTALL WIDGET: %s", path);
+        // Post installation event
+        CONTROLLER_POST_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::InstallWidgetEvent(
+                path, tzPkgId, Jobs::WidgetInstall::WidgetInstallationStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                        userdata, status_cb, progress_cb),
+                    installMode,
+                    pkgmgrInterface)));
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+}
+
+void wrt_uninstall_widget(
+    const char * const tzAppid,
+    void* userdata,
+    WrtInstallerStatusCallback status_cb,
+    WrtProgressCallback progress_cb,
+    std::shared_ptr<PackageManager::
+                        IPkgmgrSignal> pkgmgrSignalInterface)
+{
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        std::string tizenAppid(tzAppid);
+        _D("[WRT-API] UNINSTALL WIDGET: %s", tizenAppid.c_str());
+        // Post uninstallation event
+        CONTROLLER_POST_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::UninstallWidgetEvent(
+                tizenAppid,
+                WidgetUninstallationStruct(
+                    InstallerCallbacksTranslate::uninstallFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                        userdata, status_cb, progress_cb),
+                    pkgmgrSignalInterface
+                    )
+                )
+            );
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+}
+
+void wrt_install_plugin(
+    const char *pluginDir,
+    void *user_param,
+    WrtPluginInstallerStatusCallback status_cb,
+    WrtProgressCallback progress_cb)
+{
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        _D("[WRT-API] INSTALL PLUGIN: %s", pluginDir);
+        //Private data for status callback
+        //Resource is free in pluginInstallFinishedCallback
+        InstallerCallbacksTranslate::PluginStatusCallbackStruct*
+        callbackStruct =
+            new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
+                user_param, status_cb, progress_cb);
+
+        CONTROLLER_POST_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::InstallPluginEvent(
+                std::string(pluginDir),
+                PluginInstallerStruct(
+                    InstallerCallbacksTranslate::
+                        pluginInstallFinishedCallback,
+                    InstallerCallbacksTranslate::
+                        installProgressCallback, callbackStruct)));
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+}
diff --git a/src_mobile/wrt-installer/wrt_installer_api.h b/src_mobile/wrt-installer/wrt_installer_api.h
new file mode 100644 (file)
index 0000000..eb2be3c
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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
+ */
+
+#ifndef WRT_INSTALLER_API_H_
+#define WRT_INSTALLER_API_H_
+
+#include <string>
+#include <stdbool.h>
+#include <stddef.h>
+#include <wrt_type.h>
+#include <wrt_install_mode.h>
+#include <pkgmgr_signal_interface.h>
+#include <memory>
+
+typedef void (*WrtInstallerInitCallback)(WrtErrStatus status,
+                                         void *data);
+typedef void (*WrtPluginInstallerStatusCallback)(WrtErrStatus status,
+                                                 void *data);
+typedef void (*WrtInstallerStatusCallback)(std::string tizenId,
+                                           WrtErrStatus status,
+                                           void *data);
+typedef void (*WrtProgressCallback)(float percent,
+                                    const char *description,
+                                    void *data);
+
+void wrt_installer_init(
+    void *userdata,
+    WrtInstallerInitCallback callback);
+void wrt_installer_shutdown(void);
+void wrt_install_widget(
+    const char *path,
+    const char *tzPkgId,
+    void *user_parameter,
+    WrtInstallerStatusCallback status_callback,
+    WrtProgressCallback progress_callback,
+    InstallMode install_mode,
+    std::shared_ptr<PackageManager::IPkgmgrSignal>
+    pkgmgrInterface
+    );
+void wrt_uninstall_widget (
+    const char * const tzAppid,
+    void* userdata,
+    WrtInstallerStatusCallback status_cb,
+    WrtProgressCallback progress_cb,
+    std::shared_ptr<PackageManager::IPkgmgrSignal>
+    pkgmgrSignalInterface);
+void wrt_install_plugin(const char *pluginDirectory,
+                        void *userData,
+                        WrtPluginInstallerStatusCallback statusCallback,
+                        WrtProgressCallback progressCallback);
+
+#endif /* WRT_INSTALLER_API_H_ */
diff --git a/src_mobile/wrt-installer/wrt_type.h b/src_mobile/wrt-installer/wrt_type.h
new file mode 100644 (file)
index 0000000..2cfb584
--- /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.
+ */
+/**
+ * @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*/
+
+    /* pkgmgr error */
+    WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND,      ///<
+    WRT_INSTALLER_ERROR_PACKAGE_INVALID,        ///< invalid widget package
+    WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION,  ///< given version is lower than existing version
+    WRT_INSTALLER_ERROR_PACKAGE_EXCUTABLE_NOT_FOUND,
+
+    WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND = 11,///<
+    WRT_INSTALLER_ERROR_MANIFEST_INVALID,       ///<
+    WRT_INSTALLER_CONFIG_NOT_FOUND,             ///< couldn't find config.xml
+                                                ///< in package.
+    WRT_INSTALLER_ERROR_CONFIG_INVALID,         ///< invalid config.xml
+
+    WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND = 21,    ///< signature file not exist.
+    WRT_INSTALLER_ERROR_SIGNATURE_INVALID,           ///< invalid signature file
+    WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED,  ///< failure in verificate signature
+    WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND = 31, ///< couldn't find root certificate.
+    WRT_INSTALLER_ERROR_CERTIFICATION_INVAID,       ///< invalid certification
+    WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED,    ///< failure in verificate certification chain.
+    WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED,        ///< expire cerification.
+
+    WRT_INSTALLER_ERROR_INVALID_PRIVILEGE = 41,     ///< invalid privilege.
+    WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION,
+
+    WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND = 51,   ///<
+
+    WRT_INSTALLER_ERROR_FATAL_ERROR = 61,           ///< failure in db operation or file opertion..
+    WRT_INSTALLER_ERROR_OUT_OF_STORAGE,             ///< failure in shortage of memory
+    WRT_INSTALLER_ERROR_OUT_OF_MEMORY,              ///< failure in shortage of RAM
+    WRT_INSTALLER_ERROR_ARGUMENT_INVALID,
+
+    /* wrt-installer error */
+    /* 121-140 : reserved for Web installer */
+
+    /* installation */
+    WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED = 121,
+    WRT_INSTALLER_ERROR_ACE_CHECK_FAILED,
+    WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED,     ///<
+    WRT_INSTALLER_ERROR_ENCRYPTION_FAILED,          ///< Failure in reousrce encrypttion
+    WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE,        ///< Failure in installing osp service
+    WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
+    WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED,
+
+    WRT_INSTALLER_ERROR_UNKNOWN = 140,              ///< do not use this error code.
+
+} WrtErrStatus;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WRT_TYPE_H_ */
diff --git a/src_wearable/CMakeLists.txt b/src_wearable/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..ee25b20
--- /dev/null
@@ -0,0 +1,186 @@
+# 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")
+
+OPTION(LB_SUPPORT "lb support" OFF)
+
+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_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}/commons
+    ${INSTALLER_SRC_DIR}/pkg-manager
+)
+
+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}/libiriwrapper.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/manifest.cpp
+    ${INSTALLER_JOBS}/widget_install/task_commons.cpp
+    ${INSTALLER_JOBS}/widget_install/task_process_config.cpp
+    ${INSTALLER_JOBS}/widget_install/task_database.cpp
+    ${INSTALLER_JOBS}/widget_install/task_configuration.cpp
+    ${INSTALLER_JOBS}/widget_install/ace_registration.cpp
+    ${INSTALLER_JOBS}/widget_install/task_file_manipulation.cpp
+    ${INSTALLER_JOBS}/widget_install/task_user_data_manipulation.cpp
+    ${INSTALLER_JOBS}/widget_install/task_smack.cpp
+    ${INSTALLER_JOBS}/widget_install/task_ace_check.cpp
+    ${INSTALLER_JOBS}/widget_install/task_manifest_file.cpp
+    ${INSTALLER_JOBS}/widget_install/task_certify.cpp
+    ${INSTALLER_JOBS}/widget_install/task_certify_level.cpp
+    ${INSTALLER_JOBS}/widget_install/task_prepare_files.cpp
+    ${INSTALLER_JOBS}/widget_install/task_recovery.cpp
+    ${INSTALLER_JOBS}/widget_install/task_install_ospsvc.cpp
+    ${INSTALLER_JOBS}/widget_install/task_update_files.cpp
+    ${INSTALLER_JOBS}/widget_install/task_remove_backup.cpp
+    ${INSTALLER_JOBS}/widget_install/task_encrypt_resource.cpp
+    ${INSTALLER_JOBS}/widget_install/task_prepare_reinstall.cpp
+    ${INSTALLER_JOBS}/widget_install/task_pkg_info_update.cpp
+    ${INSTALLER_JOBS}/widget_install/task_status_check.cpp
+    ${INSTALLER_JOBS}/widget_install/task_recovery.cpp
+    ${INSTALLER_JOBS}/widget_install/widget_security.cpp
+    ${INSTALLER_JOBS}/widget_install/directory_api.cpp
+    ${INSTALLER_JOBS}/widget_install/widget_unzip.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_remove_custom_handlers.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_db_update.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_smack.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_uninstall_ospsvc.cpp
+    ${INSTALLER_JOBS}/widget_uninstall/task_delete_pkginfo.cpp
+    ${INSTALLER_SRC_DIR}/logic/installer_logic.cpp
+    ${INSTALLER_SRC_DIR}/logic/installer_controller.cpp
+    ${INSTALLER_SRC_DIR}/misc/wac_widget_id.cpp
+    ${INSTALLER_SRC_DIR}/misc/feature_logic.cpp
+    ${INSTALLER_SRC_DIR}/misc/libxml_utils.cpp
+    ${INSTALLER_SRC_DIR}/misc/widget_location.cpp
+    ${INSTALLER_SRC_DIR}/misc/widget_install_to_external.cpp
+    ${INSTALLER_SRC_DIR}/misc/plugin_path.cpp
+    ${INSTALLER_SRC_DIR}/pkg-manager/pkgmgr_signal.cpp
+    )
+
+IF(LB_SUPPORT)
+    SET(INSTALLER_SOURCES
+        ${INSTALLER_SOURCES}
+        )
+    MESSAGE(STATUS "adding definition -DLB_SUPPORT")
+    ADD_DEFINITIONS("-DLB_SUPPORT")
+ENDIF(LB_SUPPORT)
+
+MESSAGE(STATUS "add -DSEP_INSTALLER")
+ADD_DEFINITIONS("-DSEP_INSTALLER")
+
+
+PKG_CHECK_MODULES(INSTALLER_STATIC_DEP
+    dpl-efl
+    dpl-event-efl
+    dpl-utils-efl
+    dpl-wrt-dao-ro
+    dpl-wrt-dao-rw
+    wrt-commons-custom-handler-dao-rw
+    wrt-commons-security-origin-dao
+    wrt-commons-widget-interface-dao
+    wrt-plugins-types
+    pkgmgr-installer
+    pkgmgr-parser
+    pkgmgr-info
+    web-provider
+    libsmack
+    REQUIRED
+)
+
+PKG_CHECK_MODULES(SYS_INSTALLER_STATIC_DEP
+    appsvc
+    libxml-2.0
+    openssl
+    cert-svc-vcore
+    security-install
+    ecore-x
+    xmlsec1
+    libidn
+    libiri
+    libpcrecpp
+    ail
+    elementary
+    tapi
+    shortcut
+    capi-appfw-app-manager
+    app2sd
+    libprivilege-control
+    REQUIRED
+)
+
+INCLUDE_DIRECTORIES( SYSTEM ${SYS_INSTALLER_STATIC_DEP_INCLUDE_DIRS})
+
+INCLUDE_DIRECTORIES(
+    ${INSTALLER_DEP_INCLUDES}
+    ${INSTALLER_INCLUDES}
+    ${INSTALLER_STATIC_DEP_INCLUDE_DIRS}
+    ${OSP_APPFW_INCLUDES}
+    )
+
+ADD_LIBRARY(${TARGET_INSTALLER_STATIC} STATIC
+    ${INSTALLER_SOURCES}
+    )
+
+ADD_DEFINITIONS(${INSTALLER_STATIC_DEP_CFLAGS})
+ADD_DEFINITIONS(${INSTALLER_STATIC_DEP_CFLAGS_OTHERS})
+ADD_DEFINITIONS(${SYS_INSTALLER_STATIC_DEP_CFLAGS})
+ADD_DEFINITIONS(${SYS_INSTALLER_STATIC_DEP_CFLAGS_OTHERS})
+
+TARGET_LINK_LIBRARIES(${TARGET_INSTALLER_STATIC}
+    ${INSTALLER_STATIC_DEP_LIBRARIES} "-ldl"
+    ${SYS_INSTALLER_STATIC_DEP_LIBRARIES} "-ldl"
+    )
+
+#for encryption
+TARGET_LINK_LIBRARIES(${TARGET_INSTALLER_STATIC} "-lss-client" )
+
+ADD_SUBDIRECTORY(pkg-manager)
+ADD_SUBDIRECTORY(wrt-installer)
diff --git a/src_wearable/DESCRIPTION b/src_wearable/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_wearable/commons/installer_log.h b/src_wearable/commons/installer_log.h
new file mode 100755 (executable)
index 0000000..500f405
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013 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_log.h
+ * @author     Sungsu Kim(sung-su.kim@samsung.com)
+ * @version    0.1
+ * @brief
+ */
+
+#ifndef INSTALLER_LOG_H
+#define INSTALLER_LOG_H
+
+#include <unistd.h>
+#include <stdio.h>
+
+#include <dpl/log/secure_log.h>
+
+#ifdef WRT_INSTALLER_LOG
+
+#undef COLOR_WARNING
+#define COLOR_WARNING "\e[0m"
+#undef COLOR_TAG
+#define COLOR_TAG "\e[0m"
+
+#endif
+
+// For FOTA debuging
+#if 0
+#define PKGMGR_FOTA_PATH               "/opt/share/packages/.recovery/fota/"
+#define FOTA_RESULT_FILE               PKGMGR_FOTA_PATH"result.txt"
+
+#define _FLOG(prio, fmt, arg...) do { \
+        int __fd = 0;\
+        FILE* __file = NULL;\
+        __file = fopen(FOTA_RESULT_FILE, "a");\
+        if (__file == NULL) break;\
+        fprintf(__file, "[PKG_FOTA] [wrt-installer] [%s] [%s:%d] "fmt"\n", prio, __FUNCTION__, __LINE__, ##arg); \
+        fflush(__file);\
+        __fd = fileno(__file);\
+        fsync(__fd);\
+        fclose(__file);\
+} while (0)
+
+#undef _D
+#define _D(fmt, arg ...) _FLOG("D", fmt, ##arg)
+
+#undef _W
+#define _W(fmt, arg ...) _FLOG("W", fmt, ##arg)
+
+#undef _E
+#define _E(fmt, arg ...) _FLOG("E", fmt, ##arg)
+#endif
+
+
+#endif // INSTALLER_LOG_H
+
diff --git a/src_wearable/commons/wrt_common_types.h b/src_wearable/commons/wrt_common_types.h
new file mode 100644 (file)
index 0000000..cfed08f
--- /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.
+ */
+/*
+ * plugin_common_types.h
+ *
+ *      Author: Soyoung Kim(sy037.kim@samsung.com)
+ */
+
+#ifndef PLUGIN_COMMON_TYPES_H
+#define PLUGIN_COMMON_TYPES_H
+
+#include <boost/optional.hpp>
+#include <dpl/utils/widget_version.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+/**
+ * Widget version is optional
+ */
+typedef boost::optional<WidgetVersion> OptionalWidgetVersion;
+
+/* Define db type */
+typedef WrtDB::DbWidgetFeature WidgetFeature;
+typedef WrtDB::DbWidgetFeatureSet WidgetFeatureSet;
+
+typedef WrtDB::DbWidgetSize WidgetSize;
+
+typedef WrtDB::DbPluginHandle PluginHandle;
+
+enum InstallLocationType
+{
+    INSTALL_LOCATION_TYPE_UNKNOWN = 0,
+    INSTALL_LOCATION_TYPE_INTERNAL_ONLY,
+    INSTALL_LOCATION_TYPE_AUTO,
+    INSTALL_LOCATION_TYPE_PREFER_EXTERNAL,
+};
+
+#endif /* PLUGIN_COMMON_TYPES_H */
diff --git a/src_wearable/commons/wrt_error.h b/src_wearable/commons/wrt_error.h
new file mode 100644 (file)
index 0000000..ae4f2de
--- /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_INVALID_APP_ID = WRT_WM_ERRCODE + WRT_ERROR_SET(0x11),
+
+    /* 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_wearable/commons/wrt_install_mode.h b/src_wearable/commons/wrt_install_mode.h
new file mode 100644 (file)
index 0000000..d6462c6
--- /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    wrt_install_mode.h
+ * @author  Jihoon Chung (jihoon.chung@samgsung.com)
+ * @version
+ * @brief   Definition file of widget install mode class
+ */
+
+#ifndef WRT_INSTALL_MODE_H
+#define WRT_INSTALL_MODE_H
+
+class InstallMode
+{
+  public:
+    enum class Command
+    {
+        INSTALL,
+        REINSTALL,
+        RECOVERY
+    };
+    enum class Location
+    {
+        INTERNAL,
+        EXTERNAL
+    };
+    enum class RootPath
+    {
+        RW,
+        RO
+    };
+    enum class ExtensionType
+    {
+        WGT,
+        DIR
+    };
+    enum class InstallTime
+    {
+        NORMAL,
+        CSC,
+        PRELOAD,
+        FOTA,
+    };
+
+    InstallMode(Command cmd = Command::INSTALL,
+                Location lo = Location::INTERNAL,
+                RootPath root = RootPath::RW,
+                ExtensionType extensionType = ExtensionType::WGT,
+                InstallTime time = InstallTime::NORMAL) :
+        command(cmd),
+        location(lo),
+        rootPath(root),
+        extension(extensionType),
+        installTime(time),
+        removable(true)
+    {};
+
+    Command command;
+    Location location;
+    RootPath rootPath;
+    ExtensionType extension;
+    InstallTime installTime;
+    bool removable;
+    std::string cscPath;
+};
+
+#endif // WRT_INSTALL_MODE_H
+
diff --git a/src_wearable/configuration_parser/deny_all_parser.cpp b/src_wearable/configuration_parser/deny_all_parser.cpp
new file mode 100644 (file)
index 0000000..e807d5e
--- /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.
+ */
+#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_wearable/configuration_parser/deny_all_parser.h b/src_wearable/configuration_parser/deny_all_parser.h
new file mode 100644 (file)
index 0000000..d9dfe56
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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_wearable/configuration_parser/element_parser.h b/src_wearable/configuration_parser/element_parser.h
new file mode 100644 (file)
index 0000000..c4ea5ba
--- /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 <cstring>
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+#include <dpl/exception.h>
+#include <dpl/string.h>
+#include <dpl/shared_ptr.h>
+#include <dpl/enable_shared_from_this.h>
+
+struct XmlAttribute
+{
+    DPL::String prefix;
+    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 std::shared_ptr<ElementParser> ElementParserPtr;
+
+class ElementParser : public std::enable_shared_from_this<ElementParser>
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ParseError)
+    };
+    typedef std::function<ElementParserPtr(void)> 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_wearable/configuration_parser/ignoring_parser.cpp b/src_wearable/configuration_parser/ignoring_parser.cpp
new file mode 100644 (file)
index 0000000..087e6d5
--- /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        ignoring_parser.cpp
+ * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+#include "ignoring_parser.h"
+
+#include <functional>
+#include <memory>
+
+IgnoringParser::IgnoringParser() : ElementParser()
+{}
+
+ElementParserPtr IgnoringParser::Create()
+{
+    return ElementParserPtr(new IgnoringParser());
+}
+
+ElementParserPtr IgnoringParser::Reuse()
+{
+    return shared_from_this();
+}
+
+ElementParser::ActionFunc IgnoringParser::GetElementParser(const DPL::String& /*ns*/,
+                                                           const DPL::String& /*name*/)
+{
+    return std::bind(&IgnoringParser::Reuse, this);
+}
+
+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_wearable/configuration_parser/ignoring_parser.h b/src_wearable/configuration_parser/ignoring_parser.h
new file mode 100644 (file)
index 0000000..b14f1ad
--- /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_wearable/configuration_parser/libiriwrapper.cpp b/src_wearable/configuration_parser/libiriwrapper.cpp
new file mode 100644 (file)
index 0000000..6d8de2a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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_wearable/configuration_parser/libiriwrapper.h b/src_wearable/configuration_parser/libiriwrapper.h
new file mode 100644 (file)
index 0000000..b0b3e86
--- /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_wearable/configuration_parser/parser_runner.cpp b/src_wearable/configuration_parser/parser_runner.cpp
new file mode 100644 (file)
index 0000000..237d984
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * 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 "stdio.h"
+
+#include <stack>
+#include <libxml/xmlreader.h>
+#include <dpl/binary_queue.h>
+#include <dpl/assert.h>
+#include <dpl/file_input.h>
+
+#include <installer_log.h>
+
+class ParserRunner::Impl
+{
+    static void logErrorLibxml2(void *, const char *msg, ...)
+    {
+        char buffer[300];
+        va_list args;
+        va_start(args, msg);
+        vsnprintf(buffer, 300, msg, args);
+        va_end(args);
+        _E("%s", buffer);
+    }
+
+    static void logWarningLibxml2(void *, const char *msg, ...)
+    {
+        char buffer[300];
+        va_list args;
+        va_start(args, msg);
+        vsnprintf(buffer, 300, msg, args);
+        va_end(args);
+        _W("%s", buffer);
+    }
+
+  public:
+    bool Validate(const std::string& filename, const std::string& schema)
+    {
+        int ret = -1;
+        xmlSchemaParserCtxtPtr ctx;
+        xmlSchemaValidCtxtPtr vctx;
+        xmlSchemaPtr xschema;
+        ctx = xmlSchemaNewParserCtxt(schema.c_str());
+        if (ctx == NULL) {
+            _E("xmlSchemaNewParserCtxt() Failed");
+            return false;
+        }
+        xschema = xmlSchemaParse(ctx);
+        if (xschema == NULL) {
+            _E("xmlSchemaParse() Failed");
+            return false;
+        }
+        vctx = xmlSchemaNewValidCtxt(xschema);
+        if (vctx == NULL) {
+            _E("xmlSchemaNewValidCtxt() Failed");
+            return false;
+        }
+        xmlSchemaSetValidErrors(vctx, (xmlSchemaValidityErrorFunc)&logErrorLibxml2, (xmlSchemaValidityWarningFunc) &logWarningLibxml2, NULL);
+        ret = xmlSchemaValidateFile(vctx, filename.c_str(), 0);
+        if (ret == -1) {
+            _E("xmlSchemaValidateFile() failed");
+            return false;
+        } else if (ret == 0) {
+            _E("Config is Valid");
+            return true;
+        } else {
+            _E("Config Validation Failed with error code %d", ret);
+            return false;
+        }
+        return true;
+    }
+
+    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:
+                    _W("Ignoring Node of Type: %d", xmlTextReaderNodeType(m_reader));
+                    break;
+                }
+
+                if (m_parsingError) {
+                    _E("Parsing error occured: %ls", m_errorMsg.c_str());
+                    ThrowMsg(ElementParser::Exception::ParseError, m_errorMsg);
+                }
+            }
+
+            if (m_parsingError) {
+                _E("Parsing error occured: %ls", m_errorMsg.c_str());
+                ThrowMsg(ElementParser::Exception::ParseError, m_errorMsg);
+            }
+
+            while (!m_stack.empty()) {
+                VerifyAndRemoveCurrentElementParser();
+            }
+        }
+        Catch(ElementParser::Exception::Base)
+        {
+            CleanupParserRunner();
+            _E("%s", _rethrown_exception.DumpToString().c_str());
+            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 = GetName();
+        element.value = GetValue();
+        element.lang = GetLanguageTag();
+        element.ns = GetNamespace();
+
+        _D("value: %ls, lang: %ls, ns: %ls)",
+            element.value.c_str(), element.lang.c_str(), element.ns.c_str());
+
+        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.ns = GetAttributeNamespace();
+            attribute.prefix = GetNamePrefix();
+            attribute.name = GetNameWithoutNamespace();
+            attribute.value = GetValue();
+            attribute.lang = GetLanguageTag();
+            _D("Attribute name: %ls, value: %ls, prefix: %ls, namespace: %ls, lang: %ls",
+                attribute.name.c_str(), attribute.value.c_str(), attribute.prefix.c_str(),
+                attribute.ns.c_str(), attribute.lang.c_str());
+            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 GetAttributeNamespace() const
+    {
+        DPL::String ret_value;
+        const xmlChar* value = xmlTextReaderLookupNamespace(m_reader, NULL);
+        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 GetNamePrefix() const
+    {
+        DPL::String ret_value;
+        const xmlChar* value = xmlTextReaderPrefix(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)
+    {
+        _E("LibXML:  %ls", msg.c_str());
+        m_parsingError = true;
+        m_errorMsg = m_errorMsg + DPL::FromASCIIString("\n");
+        m_errorMsg = m_errorMsg + msg;
+    }
+
+    void StructuredErrorHandler(xmlErrorPtr error)
+    {
+        _E("LibXML:  %s", 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())
+{}
+
+bool ParserRunner::Validate(const std::string& filename, const std::string& schema)
+{
+    return m_impl->Validate(filename, schema);
+}
+
+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_wearable/configuration_parser/parser_runner.h b/src_wearable/configuration_parser/parser_runner.h
new file mode 100644 (file)
index 0000000..c5c0714
--- /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        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:
+    bool Validate(const std::string& filename, const std::string& schema);
+
+    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_wearable/configuration_parser/root_parser.h b/src_wearable/configuration_parser/root_parser.h
new file mode 100755 (executable)
index 0000000..a54b30d
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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 <functional>
+
+#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 std::bind(&RootParser<ta_Parser>::OnWidgetElement, this);
+        } 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*/) { }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/) { }
+
+    virtual void Accept(const Text& /*text*/) { }
+
+    virtual void Verify() { }
+
+  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_wearable/configuration_parser/widget_parser.cpp b/src_wearable/configuration_parser/widget_parser.cpp
new file mode 100755 (executable)
index 0000000..db5c3fa
--- /dev/null
@@ -0,0 +1,3471 @@
+/*
+ * 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 "wrt-commons/i18n-dao-ro/i18n_dao_read_only.h"
+#include <dpl/utils/warp_iri.h>
+#include <dpl/utils/mime_type_utils.h>
+#include <language_subtag_rst_tree.h>
+#include <algorithm>
+#include <cerrno>
+#include <climits>
+#include <cmath>
+#include <cstdlib>
+#include <cstdio>
+#include <functional>
+#include <locale>
+#include <memory>
+#include <string>
+#include <boost/optional.hpp>
+
+#include <dpl/foreach.h>
+#include <dpl/platform.h>
+#include <dpl/utils/warp_iri.h>
+#include <dpl/utils/mime_type_utils.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <iri.h>
+#include <pcrecpp.h>
+
+#include <deny_all_parser.h>
+#include <ignoring_parser.h>
+#include <installer_log.h>
+#include <language_subtag_rst_tree.h>
+#include <libiriwrapper.h>
+
+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 {
+        _W("dir attribute has wrong value: %ls ", attribute.value.c_str());
+        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);
+        break;
+    }
+}
+} // namespace Unicode
+
+class InnerElementsParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return std::bind(&InnerElementsParser::Other, this);
+    }
+
+    virtual void Accept(const Element& /*element*/)
+    {}
+
+    virtual void Accept(const Text& text)
+    {
+        if (!m_text) {
+            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) {
+            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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+  private:
+    boost::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 std::bind(&NameParser::Other, this);
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        m_lang = element.lang;
+        m_name = L"";
+    }
+
+    virtual void Accept(const Text& text)
+    {
+        if (!m_name) {
+            m_name = text.value;
+        } else {
+            *m_name += text.value;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (attribute.name == L"short") {
+            if (!m_shortName) {
+                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) {
+            NormalizeString(m_name);
+            NormalizeString(m_shortName);
+            if (!!m_name) {
+                Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
+            }
+            data.name = m_name;
+            if (!!m_shortName) {
+                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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+  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_WARP
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return std::bind(&AccessParser::Other, this);
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        // for tizen web apps WARP should be used
+        if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
+            element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_standardType = STANDARD_TYPE_WARP;
+        }
+    }
+
+    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;
+            }
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        switch (m_standardType) {
+        case STANDARD_TYPE_WARP:
+            AcceptWac(attribute);
+            break;
+        default:
+            _E("Error in Access tag - unknown standard.");
+            break;
+        }
+    }
+
+    void VerifyWac()
+    {
+        WarpIRI iri;
+        iri.set(m_strIRIOrigin, false);
+
+        if (!iri.isAccessDefinition()) {
+            _W("Access list element: %ls is not acceptable by WARP standard and will be ignored!",
+                m_strIRIOrigin.c_str());
+            return;
+        }
+
+        if(m_strIRIOrigin == L"*") //wildcard match means yes for subdomains
+        {
+            m_bSubDomainAccess = true;
+        }
+
+        ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
+                                                m_bSubDomainAccess);
+        //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
+        m_data.accessInfoSet.insert(accessInfo);
+    }
+
+    virtual void Verify()
+    {
+        switch (m_standardType) {
+        case STANDARD_TYPE_WARP:
+            VerifyWac();
+            break;
+        default:
+            _E("Error in Access tag - unknown standard.");
+            break;
+        }
+    }
+
+    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(shared_from_this())));
+    }
+
+  private:
+    DPL::String m_strIRIOrigin;
+    bool m_bSubDomainAccess;
+    StandardType m_standardType;
+    bool m_network;
+    ConfigParserData& m_data;
+};
+
+class DescriptionParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return std::bind(&DescriptionParser::Other, this);
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        m_lang = element.lang;
+        m_description = L"";
+    }
+
+    ElementParserPtr Other()
+    {
+        return ElementParserPtr(new InnerElementsParser(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+    virtual void Accept(const Text& text)
+    {
+        if (!m_description) {
+            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) {
+            if (!!m_description) {
+                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 std::bind(&AuthorParser::Other, this);
+    }
+
+    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(
+                                    std::static_pointer_cast<ElementParser>(
+                                        shared_from_this())));
+    }
+
+  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 std::bind(&LicenseParser::Other, this);
+    }
+
+    LicenseParser(Unicode::Direction direction,
+                  ConfigParserData& data) :
+        m_data(data),
+        m_ignore(true),
+        m_textDirection(direction)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (!m_license) {
+            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) {
+                m_licenseHref = attribute.value;
+            } else if (attribute.name == L"file" && !m_licenseFile) {
+                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) {
+            if (!!m_license) {
+                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(shared_from_this())));
+    }
+
+  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
+{
+    DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
+
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    IconParser(ConfigParserData& data) : ElementParser(),
+        m_data(data), m_isSmall(false)
+    {}
+
+    IconParser(ConfigParserData& data, bool isSmall) : ElementParser(),
+        m_data(data), m_isSmall(isSmall)
+    {}
+
+    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) {
+            _W("src attribute of icon element is mandatory - ignoring");
+            return;
+        }
+
+        Try
+        {
+            ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
+            icon.width = m_width;
+            icon.height = m_height;
+            icon.isSmall = m_isSmall;
+
+            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);
+            }
+        }
+        Catch(BadSrcError)
+        {
+            _W("src attribute is invalid: %ls", (*m_src).c_str());
+        }
+    }
+
+  private:
+    ConfigParserData& m_data;
+    DPL::OptionalString m_src;
+    DPL::OptionalInt m_width;
+    DPL::OptionalInt m_height;
+    bool m_isSmall;
+
+    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();
+            } else {
+                return valueInt;
+            }
+        }
+        return DPL::OptionalInt();
+    }
+
+    /**
+     * @brief delocalizePath removes locales folder from relative path if
+     * neccessary
+     * @param source source string
+     *
+     * @throw BadSrcError if string is bad value of src attribute
+     *
+     * @return corrected string
+     */
+    static DPL::String delocalizeSrcPath(const DPL::String & source)
+    {
+        static const DPL::String localeFolder(L"locales/");
+        static const int index = localeFolder.size();
+
+        DPL::String result = source;
+
+        if (source.substr(0, index) == localeFolder) {
+            size_t pos = result.find_first_of('/', index);
+            if (pos != std::string::npos && pos + 1 < source.size()) {
+                result = result.substr(pos + 1, source.size());
+            } else {
+                Throw(BadSrcError);
+            }
+        }
+        return result;
+    }
+};
+
+class ContentParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    ContentParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        m_namespace = element.ns;
+    }
+
+    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)
+            {
+                m_encoding = mimeAttributes[L"charset"];
+            }
+        } else if (attribute.name == L"encoding") {
+            if (!value.empty()) {
+                m_encoding = value;
+            }
+        }
+    }
+
+    virtual void Verify()
+    {
+        if(!!m_data.startFileEncountered)
+        {
+            if(m_data.startFileNamespace == m_namespace
+                || m_namespace != ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                return;
+            }
+            //else continue -> if previous item was not in tizen namespace
+        }
+
+        m_data.startFileEncountered = true;
+        m_data.startFileNamespace = m_namespace;
+
+        if (m_namespace == ConfigurationNamespace::TizenWebAppNamespaceName &&
+                (!m_src || m_src->empty())) {
+            ThrowMsg(Exception::ParseError, "content element must have correct src element");
+        }
+
+        if (!!m_src) {
+            m_data.startFile = m_src;
+            m_data.startFileContentType = m_type;
+            if (!!m_encoding) {
+                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;
+    DPL::String m_namespace;
+};
+
+class PreferenceParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    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) {
+            _W("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 SettingParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    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 AppControlParser : public ElementParser
+{
+  public:
+    struct SourceParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (!m_value || *m_value == L"") {
+                return;
+            }
+
+            m_data.m_src = *m_value;
+        }
+
+        SourceParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct OperationParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (!m_value || *m_value == L"") {
+                return;
+            }
+
+            m_data.m_operation = *m_value;
+        }
+
+        OperationParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct UriParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            // exception
+            DPL::String ignoreUri(L"file");
+
+            if (!!m_value && *m_value == ignoreUri)
+            {
+                _D("exception : '%ls' scheme will be ignored.", (*m_value).c_str());
+                m_value = DPL::OptionalString();
+            }
+
+            if (!m_value || *m_value == L"") {
+                return;
+            }
+
+            DPL::String wildString(L"*/*");
+            if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
+                && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
+            {
+                m_data.m_uriList.insert(*m_value);
+            } else {
+                _D("Ignoring uri with name %ls", (*m_value).c_str());
+            }
+        }
+
+        UriParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct MimeParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Accept(const Element& /*element*/)
+        {}
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (!m_value || *m_value == L"") {
+                return;
+            }
+
+            DPL::String wildString(L"*/*");
+            if ((m_data.m_mimeList.find(wildString) ==
+                 m_data.m_mimeList.end())
+                && (m_data.m_mimeList.find(*m_value) ==
+                    m_data.m_mimeList.end()))
+            {
+                m_data.m_mimeList.insert(*m_value);
+            } else {
+                _D("Ignoring mime with name %ls", (*m_value).c_str());
+            }
+        }
+
+        MimeParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    struct DispositionParser : 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)
+        {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_value = attribute.value;
+                    NormalizeString(m_value);
+                }
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (!m_value || *m_value == L"") {
+                return;
+            }
+
+            DPL::String windowString(L"window");
+            DPL::String inlineString(L"inline");
+
+            if (*m_value == L"window") {
+                m_data.m_disposition =
+                    ConfigParserData::AppControlInfo::Disposition::WINDOW;
+            } else if (*m_value == L"inline") {
+                m_data.m_disposition =
+                    ConfigParserData::AppControlInfo::Disposition::INLINE;
+            } else {
+                _D("Ignoring dispostion value %ls", (*m_value).c_str());
+            }
+        }
+
+        DispositionParser(ConfigParserData::AppControlInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        bool m_properNamespace;
+        DPL::OptionalString m_value;
+        ConfigParserData::AppControlInfo& m_data;
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& name)
+    {
+        if (name == L"src") {
+            return std::bind(&AppControlParser::OnSourceElement, this);
+        } else if (name == L"operation") {
+            return std::bind(&AppControlParser::OnOperationElement, this);
+        } else if (name == L"uri") {
+            return std::bind(&AppControlParser::OnUriElement, this);
+        } else if (name == L"mime") {
+            return std::bind(&AppControlParser::OnMimeElement, this);
+        } else if (name == L"disposition") {
+            return std::bind(&AppControlParser::OnDispositionElement, this);
+        } else {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        _W("namespace for app service = %ls", element.ns.c_str());
+        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_appControl.m_src == L"") {
+            ThrowMsg(Exception::ParseError, "service element must have src element");
+        }
+
+        if (m_appControl.m_operation == L"") {
+            ThrowMsg(Exception::ParseError, "service element must have operation element");
+        }
+
+        auto res = std::find(m_data.appControlList.begin(), m_data.appControlList.end(), m_appControl);
+        if(res != m_data.appControlList.end()) {
+            ThrowMsg(Exception::ParseError, "service element must be unique");
+        }
+
+#ifdef NFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY
+        // XXX This feature should be retained to Tizen 2.2 only.
+        // NFC exception handling which was requested from Tizen Device API team.
+
+        const DPL::String exceptionNfcOperation =
+                       L"http://tizen.org/appcontrol/operation/nfc/transaction";
+        const DPL::String exceptionNfcUri  = L"nfc://secure/aid/";
+        const DPL::String divertingNfcUri1 = L"nfc://secure/SIM1/aid/";
+        const DPL::String divertingNfcUri2 = L"nfc://secure/eSE/aid/";
+
+        if (m_appControl.m_operation == exceptionNfcOperation
+            && m_appControl.m_mimeList.empty()
+            && m_appControl.m_uriList.size() == 1
+            && (m_appControl.m_uriList.begin())->compare(0, exceptionNfcUri.length(), exceptionNfcUri) == 0)
+        {
+            DPL::String originalUri = *m_appControl.m_uriList.begin();
+            DPL::String newUri = originalUri;
+
+            newUri.replace(0, exceptionNfcUri.length(), divertingNfcUri1);
+            m_appControl.m_uriList.erase(m_appControl.m_uriList.begin());
+            m_appControl.m_uriList.insert(newUri);
+            m_data.appControlList.push_back(m_appControl);
+            _D("NFC exception : %ls -> %ls", originalUri.c_str(), newUri.c_str());
+
+            newUri = originalUri;
+            newUri.replace(0, exceptionNfcUri.length(), divertingNfcUri2);
+            m_appControl.m_uriList.erase(m_appControl.m_uriList.begin());
+            m_appControl.m_uriList.insert(newUri);
+            m_data.appControlList.push_back(m_appControl);
+            _D("NFC exception : %ls -> %ls", originalUri.c_str(), newUri.c_str());
+
+            return;
+        }
+#endif // NFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY
+
+        m_data.appControlList.push_back(m_appControl);
+    }
+
+    ElementParserPtr OnSourceElement()
+    {
+        return ElementParserPtr(new SourceParser(m_appControl));
+    }
+
+    ElementParserPtr OnOperationElement()
+    {
+        return ElementParserPtr(new OperationParser(m_appControl));
+    }
+
+    ElementParserPtr OnUriElement()
+    {
+        return ElementParserPtr(new UriParser(m_appControl));
+    }
+
+    ElementParserPtr OnMimeElement()
+    {
+        return ElementParserPtr(new MimeParser(m_appControl));
+    }
+
+    ElementParserPtr OnDispositionElement()
+    {
+        return ElementParserPtr(new DispositionParser(m_appControl));
+    }
+
+    AppControlParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_appControl(L"")
+    {}
+
+  private:
+    ConfigParserData& m_data;
+    ConfigParserData::AppControlInfo m_appControl;
+};
+
+class ApplicationParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        if (m_properNamespace) {
+            ThrowMsg(Exception::ParseError, "application element must be empty");
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"id") {
+                m_id = attribute.value;
+                NormalizeAndTrimSpaceString(m_id);
+            } else if (attribute.name == L"package") {
+                m_package = attribute.value;
+            } else if (attribute.name == L"required_version") {
+                m_version = attribute.value;
+                NormalizeString(m_version);
+            } else {
+                ThrowMsg(Exception::ParseError,
+                         "unknown attribute '" +
+                         DPL::ToUTF8String(attribute.name) +
+                         "' in application element");
+            }
+        }
+    }
+
+    virtual void Verify()
+    {
+        if(m_data.didFoundTizenApplicationElement)
+        {
+            ThrowMsg(Exception::ParseError, "tizen:application element must occur only once");
+        }
+        m_data.didFoundTizenApplicationElement = true;
+
+        VerifyIdAndPackage();
+        VerifyVersion();
+    }
+
+    ApplicationParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_id(DPL::OptionalString()),
+        m_version(DPL::OptionalString()),
+        m_properNamespace(false)
+    {}
+
+    static const char* const REGEXP_ID;
+
+  private:
+    void VerifyIdAndPackage()
+    {
+        if (!m_package)
+        {
+            ThrowMsg(Exception::ParseError,
+                     "application element must have package attribute");
+        }
+        else
+        {
+            pcrecpp::RE re(REGEXP_PACKAGE);
+            if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid format of package attribute");
+            }
+        }
+
+        if (!m_id) {
+            ThrowMsg(Exception::ParseError,
+                     "application element must have id attribute");
+        }
+        else
+        {
+            std::string package;
+            pcrecpp::RE re(REGEXP_ID);
+            if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid format of id attribute");
+            }
+            if (package != DPL::ToUTF8String(*m_package))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid package prefix in id attribute");
+            }
+        }
+
+        m_data.tizenAppId = m_id;
+        m_data.tizenPkgId = m_package;
+    }
+
+    void VerifyVersion()
+    {
+        if (!m_version)
+        {
+            ThrowMsg(Exception::ParseError,
+                     "application element must have required_version attribute");
+        }
+        else
+        {
+            pcrecpp::RE re(REGEXP_VERSION);
+            if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
+            {
+                ThrowMsg(Exception::ParseError,
+                         "invalid format of version attribute");
+            }
+        }
+
+        m_data.tizenMinVersionRequired = m_version;
+    }
+
+    static const char* const REGEXP_PACKAGE;
+    static const char* const REGEXP_VERSION;
+
+    ConfigParserData& m_data;
+    DPL::OptionalString m_id;
+    DPL::OptionalString m_package;
+    DPL::OptionalString m_version;
+    bool m_properNamespace;
+};
+
+const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
+const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
+const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)*";
+
+class SplashParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace)
+        {
+            if (attribute.name == L"src") {
+                if (attribute.value.size() > 0) {
+                    m_src = attribute.value;
+                }
+            }
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (!m_src)
+        {
+            _W("src attribute of splash element is mandatory - ignoring");
+            return;
+        }
+
+        m_data.splashImgSrc = m_src;
+    }
+
+    SplashParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+  private:
+    DPL::OptionalString m_src;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+class BackgroundParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (attribute.name == L"src") {
+            if (attribute.value.size() > 0) {
+                m_src = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& /*element*/)
+    {}
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (!m_src) {
+            _W("src attribute of background element is mandatory - ignoring");
+            return;
+        }
+
+        m_data.backgroundPage = m_src;
+    }
+
+    explicit BackgroundParser(ConfigParserData& data) :
+        m_data(data)
+    {}
+
+  private:
+    DPL::OptionalString m_src;
+    ConfigParserData& m_data;
+};
+
+class PrivilegeParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+        _D("element");
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"name") {
+                m_feature.name = attribute.value;
+                m_privilege.name = attribute.value;
+            }
+        }
+    }
+
+    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 {
+                    _D("Ignoring feature with name %ls", m_feature.name.c_str());
+                }
+            }
+        }
+
+        LibIri::Wrapper iriPrivilege(
+            DPL::ToUTF8String(m_privilege.name).c_str());
+
+        if (m_privilege.name != L"") {
+            if (iriPrivilege.Validate()) {
+                if (m_data.privilegeList.find(m_privilege) ==
+                    m_data.privilegeList.end())
+                {
+                    m_data.privilegeList.insert(m_privilege);
+                } else {
+                    _D("Ignoring privilege with name %ls", m_privilege.name.c_str());
+                }
+            }
+        }
+    }
+
+    PrivilegeParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_feature(L""),
+        m_privilege(L""),
+        m_properNamespace(false)
+    {}
+
+  private:
+    ConfigParserData& m_data;
+    ConfigParserData::Feature m_feature;
+    ConfigParserData::Privilege m_privilege;
+    bool m_properNamespace;
+};
+
+class CategoryParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+        LogDebug("element");
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"name") {
+                if (attribute.value.size() > 0) {
+                    m_name = attribute.value;
+                }
+            }
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (!m_name) {
+            _W("name attribute of category element is mandatory - ignoring");
+            return;
+        }
+
+        if (m_data.categoryList.find(*m_name) ==
+            m_data.categoryList.end())
+        {
+            m_data.categoryList.insert(*m_name);
+        }
+
+    }
+
+    explicit CategoryParser(ConfigParserData& data) :
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+  private:
+    DPL::OptionalString m_name;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+#ifdef DBOX_ENABLED
+class AppWidgetParser : public ElementParser
+{
+  public:
+
+    struct BoxLabelParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (m_properNamespace) {
+                 m_lang = attribute.lang;
+            }
+        }
+        virtual void Accept(const Element& element)
+        {
+            if (element.ns ==
+                ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                m_properNamespace = true;
+            }
+        }
+
+        virtual void Accept(const Text& text)
+        {
+            if (m_properNamespace) {
+                m_label = text.value;
+            }
+        }
+
+        virtual void Verify()
+        {
+            std::pair<DPL::String, DPL::String> boxLabel;
+            if (m_label.empty()) {
+                _W("box-label element is empty");
+                boxLabel.first = DPL::FromUTF8String("");
+                boxLabel.second = DPL::FromUTF8String("");
+                m_data.m_label.push_back(boxLabel);
+            }
+            else {
+                boxLabel.first = m_lang;
+                boxLabel.second = m_label;
+                m_data.m_label.push_back(boxLabel);
+            }
+        }
+
+        BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        DPL::String m_lang;
+        DPL::String m_label;
+        bool m_properNamespace;
+        ConfigParserData::LiveboxInfo& m_data;
+    };
+
+    struct BoxIconParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (m_properNamespace) {
+                if (attribute.name == L"src") {
+                    m_icon = attribute.value;
+                }
+            }
+        }
+
+        virtual void Accept(const Element& element)
+        {
+            if (element.ns ==
+                ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                m_properNamespace = true;
+            }
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Verify()
+        {
+            if (m_icon.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "src attribute of box-icon element is mandatory - ignoring");
+            }
+            if (!m_data.m_icon.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "<tizen:box-icon /> element should occur as 0 or 1 time");
+            }
+            m_data.m_icon = m_icon;
+        }
+
+        explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+      private:
+        DPL::String m_icon;
+        bool m_properNamespace;
+        ConfigParserData::LiveboxInfo& m_data;
+    };
+
+    struct BoxContentParser : public ElementParser
+    {
+        struct BoxSizeParser : public ElementParser
+        {
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                                const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const XmlAttribute& attribute)
+            {
+                if (m_properNamespace) {
+                    if (attribute.name == L"preview") {
+                        m_preview = attribute.value;
+                    }
+                    if (attribute.name == L"use-decoration") {
+                        m_useDecoration = attribute.value;
+                    }
+                }
+            }
+
+            virtual void Accept(const Element& element)
+            {
+                if (element.ns ==
+                    ConfigurationNamespace::TizenWebAppNamespaceName)
+                {
+                    m_properNamespace = true;
+                }
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (m_properNamespace) {
+                    m_size = text.value;
+                }
+            }
+
+            virtual void Verify()
+            {
+                if(m_size.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "size is mandatory - ignoring");
+                }
+
+                if (m_useDecoration.empty() || CheckIfNotTrueNorFalse(m_useDecoration)) {
+                    m_useDecoration = L"true"; // default value
+                }
+
+                ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
+                boxSizeInfo.m_size = m_size;
+                boxSizeInfo.m_preview = m_preview;
+                boxSizeInfo.m_useDecoration = m_useDecoration;
+                m_data.m_boxSize.push_back(boxSizeInfo);
+            }
+
+            explicit BoxSizeParser(
+                ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+            {}
+
+          private:
+            DPL::String m_size;
+            DPL::String m_preview;
+            DPL::String m_useDecoration;
+            bool m_properNamespace;
+            ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
+        };
+
+        struct PdParser : public ElementParser
+        {
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                                const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const XmlAttribute& attribute)
+            {
+                if (m_properNamespace) {
+                    if (attribute.name == L"src") {
+                        m_src = attribute.value;
+                    } else if (attribute.name == L"width") {
+                        m_width = attribute.value;
+                    } else if (attribute.name == L"height") {
+                        m_height = attribute.value;
+                    } else if (attribute.name == L"fast-open") {
+                        m_fastOpen= attribute.value;
+                    }
+                }
+            }
+
+            virtual void Accept(const Element& element)
+            {
+                if (element.ns ==
+                    ConfigurationNamespace::TizenWebAppNamespaceName)
+                {
+                    m_properNamespace = true;
+                }
+            }
+
+            virtual void Accept(const Text& /*text*/)
+            {}
+
+            virtual void Verify()
+            {
+                if (m_src.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "src attribute of pd element is mandatory - ignoring");
+                }
+
+                if (m_width.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "width attribute of pd element is mandatory - ignoring");
+                }
+
+                if (m_height.empty()) {
+                    ThrowMsg(Exception::ParseError,
+                        "height attribute of pd element is mandatory - ignoring");
+                }
+
+                if (!ConvertToInt(m_width)) {
+                    ThrowMsg(Exception::ParseError,
+                        "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
+                }
+
+
+                DPL::OptionalInt height = ConvertToInt(m_height);
+
+                if (!height) {
+                    ThrowMsg(Exception::ParseError,
+                        "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
+                }
+
+                if (*height < 1) {
+                    m_height = L"1";
+                    _D("height attribute of pd element shouldn't be less than 1. Changed to 1 from %d", *height);
+                } else if (*height > 380){
+                    m_height = L"380";
+                    _D("height attribute of pd element shouldn't be greater than 380. Changed to 380 from %d", *height);
+                }
+
+                if (!m_data.m_pdSrc.empty()) {
+                    ThrowMsg(Exception::ParseError, "<tizen:pd> element should occur as 0 or 1 time");
+                }
+
+                m_data.m_pdSrc = m_src;
+                m_data.m_pdWidth = m_width;
+                m_data.m_pdHeight = m_height;
+                m_data.m_pdFastOpen = m_fastOpen;
+            }
+
+            explicit PdParser(
+                ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+            {}
+
+          private:
+            DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
+            {
+                char * endptr;
+                std::string tempStr = DPL::ToUTF8String(intAsString);
+                const char * intAsString_c = tempStr.c_str();
+                errno = 0;
+                long int intAsString_i = strtol(intAsString_c, &endptr, 10);
+
+                if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
+                        || intAsString_i > INT_MAX || intAsString_i < INT_MIN
+                        || *endptr != '\0') {
+                    return DPL::OptionalInt();
+                }
+
+                return static_cast<int>(intAsString_i);
+            }
+
+            DPL::String m_src;
+            DPL::String m_width;
+            DPL::String m_height;
+            DPL::String m_fastOpen;
+
+            bool m_properNamespace;
+            ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
+        };
+
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& name)
+        {
+            if (name == L"box-size") {
+                return std::bind(&AppWidgetParser::BoxContentParser::OnBoxSizeElement, this);
+            } else if (name == L"pd") {
+                return std::bind(&AppWidgetParser::BoxContentParser::OnPdElement, this);
+            } else {
+                ThrowMsg(Exception::ParseError,
+                         "No element parser for name: " << name);
+            }
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            if (m_properNamespace) {
+                if (attribute.name == L"src") {
+                    m_box.m_boxSrc = attribute.value;
+                }
+                if (attribute.name == L"mouse-event") {
+                    m_box.m_boxMouseEvent = attribute.value;
+                }
+                if (attribute.name == L"touch-effect") {
+                    m_box.m_boxTouchEffect = attribute.value;
+                }
+            }
+        }
+
+        virtual void Accept(const Element& element)
+        {
+            if (element.ns ==
+                ConfigurationNamespace::TizenWebAppNamespaceName)
+            {
+                m_properNamespace = true;
+            }
+        }
+
+        virtual void Accept(const Text& /*text*/)
+        {}
+
+        virtual void Verify()
+        {
+            if (m_box.m_boxSrc.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "src attribute of box-content element is mandatory - ignoring");
+            }
+
+            if (m_box.m_boxMouseEvent.empty() || CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent)) {
+                m_box.m_boxMouseEvent = L"false"; // default value
+            }
+
+            if (m_box.m_boxTouchEffect.empty() || CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect)) {
+                m_box.m_boxTouchEffect = L"true"; // default value
+            }
+
+            if (m_box.m_boxSize.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "box-size element of box-content element not found - ignoring");
+            }
+
+            if (!m_data.m_boxInfo.m_boxSrc.empty()) {
+                ThrowMsg(Exception::ParseError, "<tizen:box-content> element must occur exactly 1 time");
+            }
+
+            m_data.m_boxInfo = m_box;
+        }
+
+        explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
+            ElementParser(),
+            m_properNamespace(false),
+            m_data(data)
+        {}
+
+        ElementParserPtr OnBoxSizeElement()
+        {
+            return ElementParserPtr(new BoxSizeParser(m_box));
+        }
+
+        ElementParserPtr OnPdElement()
+        {
+            return ElementParserPtr(new PdParser(m_box));
+        }
+
+      private:
+        bool m_properNamespace;
+        ConfigParserData::LiveboxInfo& m_data;
+        ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& name)
+    {
+        if (name == L"box-label") {
+            return std::bind(&AppWidgetParser::OnBoxLabelElement, this);
+        } else if (name == L"box-icon") {
+            return std::bind(&AppWidgetParser::OnBoxIconElement, this);
+        } else if (name == L"box-content") {
+            return std::bind(&AppWidgetParser::OnBoxContentElement, this);
+        } else {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"id") {
+                m_liveboxId = attribute.value;
+            } else if (attribute.name == L"primary") {
+                m_primary = attribute.value;
+            } else if (attribute.name == L"auto-launch") {
+                m_autoLaunch = attribute.value;
+            } else if (attribute.name == L"update-period") {
+                m_updatePeriod = attribute.value;
+            } else if (attribute.name == L"type") {
+                m_type = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns ==
+            ConfigurationNamespace::TizenWebAppNamespaceName)
+        {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {}
+
+    virtual void Verify()
+    {
+        if (m_liveboxId.empty()) {
+            ThrowMsg(Exception::ParseError,
+                 "app-widget element must have id attribute");
+        }
+        else
+        {
+            pcrecpp::RE re(REGEXP_ID_STRING.c_str());
+            if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
+            {
+                ThrowMsg(Exception::ParseError,
+                     "invalid format of app-widget id attribute");
+            }
+        }
+
+        if (m_primary.empty() || CheckIfNotTrueNorFalse(m_primary))
+        {
+            m_primary = L"true";        //default value
+        }
+
+        if (!m_updatePeriod.empty())
+        {
+            char * endptr;
+            errno = 0;
+            std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
+
+            //set standard locale to fix decimal point mark - '.'
+            std::string currentLocale = setlocale(LC_NUMERIC, NULL);
+            if (NULL == setlocale(LC_NUMERIC, "C"))
+                _W("Failed to change locale to \"C\"");
+            double updatePeriod = strtod(tempStr.c_str(), &endptr);
+
+            //go back to previous locale
+            if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
+                _W("Failed to set previous locale");
+
+            if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
+                    || *endptr != '\0') {
+                ThrowMsg(Exception::ParseError,
+                    "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
+            } else if (updatePeriod < 1800.0) {
+                _D("update-period attribute of app-widget element shouldn't be less than 1800.0 - changed to 1800 from value: %ls", m_updatePeriod.c_str());
+                m_updatePeriod = L"1800.0";
+            }
+        }
+
+        if (m_autoLaunch.empty() || CheckIfNotTrueNorFalse(m_autoLaunch))
+        {
+            m_autoLaunch = L"false"; // default value
+        }
+
+        if(m_livebox.m_label.empty()) {
+            ThrowMsg(Exception::ParseError,
+                "box-label element of app-widget element not found - ignoring");
+        }
+
+        if(!m_boxContentFound) {
+            ThrowMsg(Exception::ParseError,
+                "box-content element of app-widget element not found - ignoring");
+        }
+
+        m_livebox.m_liveboxId = m_liveboxId;
+        m_livebox.m_primary = m_primary;
+        m_livebox.m_autoLaunch = m_autoLaunch;
+        m_livebox.m_updatePeriod = m_updatePeriod;
+        m_livebox.m_type = m_type;
+
+        m_data.m_livebox.push_back(m_livebox);
+    }
+
+    explicit AppWidgetParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false),
+        m_boxContentFound(false)
+    {
+        m_livebox = ConfigParserData::LiveboxInfo();
+    }
+
+    ElementParserPtr OnBoxLabelElement()
+    {
+
+        return ElementParserPtr(new BoxLabelParser(m_livebox));
+    }
+
+    ElementParserPtr OnBoxIconElement()
+    {
+        return ElementParserPtr(new BoxIconParser(m_livebox));
+    }
+
+    ElementParserPtr OnBoxContentElement()
+    {
+        m_boxContentFound = true;
+        return ElementParserPtr(new BoxContentParser(m_livebox));
+    }
+
+  private:
+    static std::string REGEXP_ID_STRING;
+    ConfigParserData& m_data;
+    ConfigParserData::LiveboxInfo m_livebox;
+    DPL::String m_liveboxId;
+    DPL::String m_primary;
+    DPL::String m_autoLaunch;
+    DPL::String m_updatePeriod;
+    DPL::String m_type;
+    bool m_properNamespace;
+    bool m_boxContentFound;
+
+    static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
+    {
+        return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
+    }
+};
+
+std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
+#endif
+
+class AllowNavigationParser : public ElementParser
+{
+  public:
+    AllowNavigationParser(ConfigParserData& data) :
+      ElementParser(),
+      m_data(data),
+      m_properNamespace(false)
+    {}
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& text)
+    {
+        if (m_properNamespace)
+        {
+            m_origin = text.value;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {
+    }
+
+    virtual void Verify()
+    {
+        if (m_data.allowNavigationEncountered || !m_properNamespace)
+        {
+            return;
+        }
+        m_data.allowNavigationEncountered = true;
+
+        if (!m_origin) {
+            _W("data is empty");
+            return;
+        }
+
+        char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
+        char* ptr = strtok(data," \n\r\t");
+        while (ptr != NULL) {
+            std::string origin = ptr;
+            ptr = strtok(NULL," \n\r\t");
+            if(origin == "*") {
+                ConfigParserData::AllowNavigationInfo info(L"*", L"*");
+                m_data.allowNavigationInfoList.push_back(info);
+                continue;
+            }
+
+            std::unique_ptr<iri_t, decltype(&iri_destroy)> iri(iri_parse(origin.c_str()), iri_destroy);
+            if (!iri->host || strlen(iri->host) == 0) {
+                // input origin should has schem and host
+                // in case of file scheme path is filled
+                // "http://"
+                _W("input origin isn't verified");
+                continue;
+            }
+            DPL::String scheme = L"*";
+            if (iri->scheme && strlen(iri->scheme) != 0) {
+                scheme = DPL::FromUTF8String(iri->scheme);
+            }
+            ConfigParserData::AllowNavigationInfo info(
+                scheme,
+                DPL::FromUTF8String(iri->host));
+            m_data.allowNavigationInfoList.push_back(info);
+        }
+        free(data);
+    }
+
+  private:
+    DPL::OptionalString m_origin;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+class CspParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    CspParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {}
+
+    virtual void Accept(const Text& text)
+    {
+        if (m_properNamespace) {
+            m_policy = text.value;
+        }
+    }
+
+    virtual void Verify()
+    {
+        if (m_data.cspPolicyEncountered) {
+            return;
+        }
+        m_data.cspPolicyEncountered = true;
+
+        if (!!m_policy) {
+            m_data.cspPolicy = *m_policy;
+        }
+    }
+
+  private:
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+    DPL::OptionalString m_policy;
+};
+
+class CspReportOnlyParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    CspReportOnlyParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const XmlAttribute& /*attribute*/)
+    {}
+
+    virtual void Accept(const Text& text)
+    {
+        if (m_properNamespace) {
+            m_policy = text.value;
+        }
+    }
+
+    virtual void Verify()
+    {
+        if (m_data.cspPolicyReportOnlyEncountered) {
+            return;
+        }
+        m_data.cspPolicyReportOnlyEncountered = true;
+
+        if (!!m_policy) {
+            m_data.cspPolicyReportOnly = *m_policy;
+        }
+    }
+
+  private:
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+    DPL::OptionalString m_policy;
+};
+
+class AccountParser : public ElementParser
+{
+  public:
+      struct IconParser : public ElementParser
+    {
+        public:
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                    const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (text.value == L"") {
+                    return;
+                }
+                m_value = text.value;
+            }
+
+            virtual void Accept(const Element& /*element*/)
+            {}
+
+            virtual void Accept(const XmlAttribute& attribute)
+            {
+                if (attribute.name == L"section") {
+                    if (attribute.value == L"Account") {
+                        m_type = ConfigParserData::IconSectionType::DefaultIcon;
+                    } else if (attribute.value == L"AccountSmall") {
+                        m_type = ConfigParserData::IconSectionType::SmallIcon;
+                    }
+                }
+            }
+
+            virtual void Verify()
+            {
+                if (!m_value || *m_value == L"") {
+                    return;
+                }
+
+                std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
+                icon.first = m_type;
+                icon.second = *m_value;
+
+                m_data.m_iconSet.insert(icon);
+            }
+
+            IconParser(ConfigParserData::AccountProvider& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_type(ConfigParserData::DefaultIcon),
+                m_data(data)
+        {}
+
+        private:
+            bool m_properNamespace;
+            ConfigParserData::IconSectionType m_type;
+            ConfigParserData::AccountProvider& m_data;
+            DPL::OptionalString m_value;
+    };
+
+      struct DisplayNameParser : public ElementParser
+    {
+        public:
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                    const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (text.value == L"") {
+                    return;
+                }
+                m_value = text.value;
+            }
+
+            virtual void Accept(const Element& element)
+            {
+                m_lang = element.lang;
+                m_value= L"";
+            }
+
+            virtual void Accept(const XmlAttribute& /*attribute*/)
+            {}
+
+            virtual void Verify()
+            {
+                if (!m_value || *m_value == L"") {
+                    return;
+                }
+
+                std::pair<DPL::String, DPL::String> name;
+                name.first = *m_lang;
+                name.second = *m_value;
+
+                m_data.m_displayNameSet.insert(name);
+            }
+
+            DisplayNameParser(ConfigParserData::AccountProvider& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+        {}
+
+        private:
+            bool m_properNamespace;
+            DPL::OptionalString m_lang;
+            DPL::OptionalString m_value;
+            ConfigParserData::AccountProvider& m_data;
+    };
+
+      struct CapabilityParser : public ElementParser
+    {
+        public:
+            virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                    const DPL::String& /*name*/)
+            {
+                return &IgnoringParser::Create; //ignore unknown according to w3c
+            }
+
+            virtual void Accept(const Text& text)
+            {
+                if (text.value == L"") {
+                    return;
+                }
+                m_value = text.value;
+            }
+
+            virtual void Accept(const Element& /*element*/)
+            {}
+
+            virtual void Accept(const XmlAttribute& /*attribute*/)
+            {}
+
+            virtual void Verify()
+            {
+                if (!m_value || *m_value == L"") {
+                    return;
+                }
+                m_data.m_capabilityList.push_back(*m_value);
+            }
+
+            CapabilityParser(ConfigParserData::AccountProvider& data) :
+                ElementParser(),
+                m_properNamespace(false),
+                m_data(data)
+        {}
+
+        private:
+            bool m_properNamespace;
+            DPL::OptionalString m_value;
+            ConfigParserData::AccountProvider& m_data;
+    };
+      virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+              const DPL::String& name)
+      {
+          if (name == L"icon") {
+              return std::bind(&AccountParser::OnIconElement, this);
+          } else if (name == L"display-name") {
+              return std::bind(&AccountParser::OnDisplayNameElement, this);
+          } else if (name == L"capability") {
+              return std::bind(&AccountParser::OnCapabilityElement, this);
+          } else {
+              return &IgnoringParser::Create; //ignore unknown according to w3c
+          }
+      }
+
+      virtual void Accept(const Text& /*text*/)
+      {}
+
+      virtual void Accept(const Element& /*element*/)
+      {}
+
+      virtual void Accept(const XmlAttribute& attribute)
+      {
+          if (attribute.name == L"multiple-account-support") {
+              if (attribute.value == L"true") {
+                  m_account.m_multiAccountSupport = true;
+              }
+          }
+      }
+
+      virtual void Verify()
+      {
+      }
+
+      ElementParserPtr OnIconElement()
+      {
+          return ElementParserPtr(new IconParser(m_account));
+      }
+
+      ElementParserPtr OnDisplayNameElement()
+      {
+          return ElementParserPtr(new DisplayNameParser(m_account));
+      }
+
+      ElementParserPtr OnCapabilityElement()
+      {
+          return ElementParserPtr(new CapabilityParser(m_account));
+      }
+
+      AccountParser(ConfigParserData& data) :
+          ElementParser(),
+          m_properNamespace(false),
+          m_multiSupport(false),
+          m_data(data),
+          m_account(data.accountProvider)
+    {
+    }
+
+  private:
+      bool m_properNamespace;
+      bool m_multiSupport;
+      ConfigParserData& m_data;
+      ConfigParserData::AccountProvider& m_account;
+};
+
+class MetadataParser : public ElementParser
+{
+  public:
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& /*name*/)
+    {
+        return &IgnoringParser::Create; //ignore unknown according to w3c
+    }
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (m_properNamespace) {
+            if (attribute.name == L"key") {
+                m_key = attribute.value;
+            } else if (attribute.name == L"value") {
+                m_value = attribute.value;
+            }
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {
+        if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            m_properNamespace = true;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        ThrowMsg(Exception::ParseError, "param element must be empty");
+    }
+
+    virtual void Verify()
+    {
+        if (!m_key) {
+            _W("metadata element must have key attribute");
+            return;
+        }
+        NormalizeString(m_key);
+        NormalizeString(m_value);
+        ConfigParserData::Metadata metaData(m_key, m_value);
+        FOREACH(it, m_data.metadataList) {
+            if (!DPL::StringCompare(*it->key, *m_key)) {
+                _E("Key isn't unique");
+                return;
+            }
+        }
+        m_data.metadataList.push_back(metaData);
+    }
+
+    MetadataParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_properNamespace(false)
+    {}
+
+  private:
+    DPL::OptionalString m_key;
+    DPL::OptionalString m_value;
+    ConfigParserData& m_data;
+    bool m_properNamespace;
+};
+
+#ifdef IME_ENABLED
+class ImeParser : public ElementParser
+{
+  public:
+    struct UuidParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create;
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {}
+
+        virtual void Accept(const Element& element)
+        {}
+
+        virtual void Accept(const Text& text)
+        {
+            if (m_uuid.empty()) {
+                m_uuid = text.value;
+            } else {
+                m_uuid += text.value;
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (m_uuid.empty()) {
+                ThrowMsg(Exception::ParseError, "uuid text is empty");
+            }
+            m_imeAppInfo.uuid = m_uuid;
+        }
+
+        UuidParser(ConfigParserData::ImeAppInfo& data) :
+            ElementParser(),
+            m_imeAppInfo(data)
+        {}
+
+      private:
+          ConfigParserData::ImeAppInfo& m_imeAppInfo;
+          DPL::String m_uuid;
+    };
+
+    struct LanguagesParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& name)
+        {
+            if (name == L"language") {
+                return std::bind(&LanguagesParser::OnLanguageElement, this);
+            } else {
+                return &IgnoringParser::Create;
+            }
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {}
+
+        virtual void Accept(const Element& element)
+        {}
+
+        virtual void Accept(const Text& text)
+        {
+            ThrowMsg(Exception::ParseError, "param element must be empty");
+        }
+
+        virtual void Verify()
+        {}
+
+        LanguagesParser(ConfigParserData::ImeAppInfo& data) :
+            ElementParser(),
+            m_imeAppInfo(data)
+        {}
+
+        ElementParserPtr OnLanguageElement()
+        {
+            return ElementParserPtr(new LanguageParser(m_imeAppInfo));
+        }
+
+      private:
+          ConfigParserData::ImeAppInfo& m_imeAppInfo;
+    };
+
+    struct LanguageParser : public ElementParser
+    {
+      public:
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                                    const DPL::String& name)
+        {
+            return &IgnoringParser::Create;
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {}
+
+        virtual void Accept(const Element& element)
+        {}
+
+        virtual void Accept(const Text& text)
+        {
+            if (m_language.empty()) {
+                m_language = text.value;
+            } else {
+                m_language += text.value;
+            }
+        }
+
+        virtual void Verify()
+        {
+            if (m_language.empty()) {
+                ThrowMsg(Exception::ParseError, "language text is empty");
+            }
+            m_imeAppInfo.languageList.insert(m_language);
+        }
+
+        LanguageParser(ConfigParserData::ImeAppInfo& data) :
+            ElementParser(),
+            m_imeAppInfo(data)
+        {}
+
+      private:
+          ConfigParserData::ImeAppInfo& m_imeAppInfo;
+          DPL::String m_language;
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& name)
+    {
+        if (name == L"uuid") {
+            return std::bind(&ImeParser::OnUuidElement, this);
+        } else if (name == L"languages") {
+            return std::bind(&ImeParser::OnLanguagesElement, this);
+        } else {
+            return &IgnoringParser::Create;
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        ThrowMsg(Exception::ParseError, "param element must be empty");
+    }
+
+    virtual void Accept(const Element& element)
+    {}
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {}
+
+    virtual void Verify()
+    {
+        if (m_imeAppInfo.uuid.empty()) {
+            ThrowMsg(Exception::ParseError, "ime element must have uuid element");
+            return;
+        }
+
+        if (m_imeAppInfo.languageList.empty()) {
+            ThrowMsg(Exception::ParseError, "ime element must have language element");
+            return;
+        }
+        m_data.imeAppInfoList.push_back(m_imeAppInfo);
+    }
+
+    ImeParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_imeAppInfo()
+    {}
+
+    ElementParserPtr OnLanguagesElement()
+    {
+        return ElementParserPtr(new LanguagesParser(m_imeAppInfo));
+    }
+
+    ElementParserPtr OnUuidElement()
+    {
+        return ElementParserPtr(new UuidParser(m_imeAppInfo));
+    }
+
+  private:
+    ConfigParserData& m_data;
+    ConfigParserData::ImeAppInfo m_imeAppInfo;
+};
+#endif
+
+#ifdef SERVICE_ENABLED
+class ServiceAppParser : public ElementParser
+{
+  public:
+    struct ServiceContentParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+           if (attribute.name == L"src") {
+               m_src = attribute.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_src.empty()) {
+                ThrowMsg(Exception::ParseError, "src attribute of service-content element is mandatory");
+            }
+
+            if (!m_serviceAppInfo.serviceContent.empty()) {
+                ThrowMsg(Exception::ParseError, "service-content element occurs more than 1 time");
+            }
+            m_serviceAppInfo.serviceContent = m_src;
+        }
+
+        explicit ServiceContentParser(ConfigParserData::ServiceAppInfo& data) :
+            ElementParser(),
+            m_serviceAppInfo(data)
+        {}
+
+      private:
+        DPL::String m_src;
+        ConfigParserData::ServiceAppInfo& m_serviceAppInfo;;
+    };
+
+    struct ServiceNameParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                            const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create;
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            m_lang = attribute.lang;
+        }
+
+        virtual void Accept(const Element& element)
+        {}
+
+        virtual void Accept(const Text& text)
+        {
+            m_name = text.value;
+        }
+
+        virtual void Verify()
+        {
+            ConfigParserData::LocalizedData& data = m_serviceAppInfo.m_localizedDataSet[m_lang];
+            if (data.name.IsNull()) {
+                NormalizeString(m_name);
+                data.name = m_name;
+            }
+        }
+
+        ServiceNameParser(ConfigParserData::ServiceAppInfo& data) :
+            ElementParser(),
+            m_serviceAppInfo(data)
+        {}
+
+      private:
+        DPL::String m_lang;
+        DPL::String m_name;
+        ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
+    };
+
+    struct ServiceIconParser : 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"src") {
+                m_icon.src = attribute.value;
+            }
+            else if (attribute.name == L"width") {
+                m_icon.width = ConvertToInt(attribute.value);
+            }
+            else if (attribute.name == L"height") {
+                m_icon.height = ConvertToInt(attribute.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_icon.src.empty()) {
+                ThrowMsg(Exception::ParseError,
+                    "src attribute of service-icon element is mandatory - ignoring");
+            }
+             m_serviceAppInfo.m_iconsList.push_back(m_icon);
+        }
+
+        explicit ServiceIconParser(ConfigParserData::ServiceAppInfo& data) :
+            ElementParser(),
+            m_icon(L""),
+            m_serviceAppInfo(data)
+        {}
+
+    private:
+        DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
+        {
+            char * endptr;
+            std::string tempStr = DPL::ToUTF8String(intAsString);
+            const char * intAsString_c = tempStr.c_str();
+            errno = 0;
+            long int intAsString_i = strtol(intAsString_c, &endptr, 10);
+
+            if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
+                    || intAsString_i > INT_MAX || intAsString_i < INT_MIN
+                    || *endptr != '\0') {
+                return DPL::OptionalInt();
+            }
+
+            return static_cast<int>(intAsString_i);
+        }
+
+      private:
+        ConfigParserData::Icon m_icon;
+        ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
+    };
+
+    struct ServiceDescriptionParser : public ElementParser
+    {
+        virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, const DPL::String& /*name*/)
+        {
+            return &IgnoringParser::Create; //ignore unknown according to w3c
+        }
+
+        virtual void Accept(const XmlAttribute& attribute)
+        {
+            m_lang = attribute.lang;
+        }
+        virtual void Accept(const Element& element)
+        {}
+
+        virtual void Accept(const Text& text)
+        {
+            m_description = text.value;
+        }
+
+        virtual void Verify()
+        {
+            ConfigParserData::LocalizedData& data = m_serviceAppInfo.m_localizedDataSet[m_lang];
+            if (data.description.IsNull()) {
+                NormalizeString(m_description);
+                data.description = m_description;
+            }
+        }
+
+        ServiceDescriptionParser(ConfigParserData::ServiceAppInfo& data) :
+            ElementParser(),
+            m_serviceAppInfo(data)
+        {}
+
+    private:
+        DPL::String m_lang;
+        DPL::String m_description;
+        ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
+    };
+
+    virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
+                                        const DPL::String& name)
+    {
+        if (name == L"service-content") {
+            return std::bind(&ServiceAppParser::OnServiceContentElement, this);
+        } else if (name == L"service-name") {
+            return std::bind(&ServiceAppParser::OnServiceNameElement, this);
+        } else if (name == L"service-icon") {
+            return std::bind(&ServiceAppParser::OnServiceIconElement, this);
+        } else if (name == L"service-description") {
+            return std::bind(&ServiceAppParser::OnServiceDescriptionElement, this);
+        } else {
+            return &IgnoringParser::Create;
+        }
+    }
+
+    virtual void Accept(const Element& element)
+    {}
+
+    virtual void Accept(const XmlAttribute& attribute)
+    {
+        if (attribute.name == L"id") {
+            if (attribute.value.size() > 0) {
+                m_serviceId = attribute.value;
+            }
+        } else if (attribute.name == L"auto_restart") {
+            if (attribute.value == L"true") {
+                m_autoRestart = true;
+            } else if (attribute.value == L"false") {
+                m_autoRestart = false;
+            } else {
+                ThrowMsg(Exception::ParseError, "Wrong boolean value");
+            }
+        } else if (attribute.name == L"on_boot") {
+            if (attribute.value == L"true") {
+                m_onBoot = true;
+            } else if (attribute.value == L"false") {
+                m_onBoot = false;
+            } else {
+                ThrowMsg(Exception::ParseError, "Wrong boolean value");
+            }
+        }
+    }
+
+    virtual void Accept(const Text& /*text*/)
+    {
+        ThrowMsg(Exception::ParseError, "param element must be empty");
+    }
+
+    virtual void Verify()
+    {
+        if (m_serviceAppInfo.serviceContent.empty()) {
+            ThrowMsg(Exception::ParseError, "service element must have service-content element");
+            return;
+        }
+
+        if (m_serviceId.empty()) {
+            ThrowMsg(Exception::ParseError, "service attribute must have id attribute");
+            return;
+        }
+        m_serviceAppInfo.serviceId = m_serviceId;
+
+        m_serviceAppInfo.autoRestart = m_autoRestart;
+
+        m_serviceAppInfo.onBoot = m_onBoot;
+
+        m_data.serviceAppInfoList.push_back(m_serviceAppInfo);
+    }
+
+    ServiceAppParser(ConfigParserData& data) :
+        ElementParser(),
+        m_data(data),
+        m_serviceAppInfo(),
+        m_onBoot(false),
+        m_autoRestart(false)
+    {}
+
+    ElementParserPtr OnServiceContentElement()
+    {
+        return ElementParserPtr(new ServiceContentParser(m_serviceAppInfo));
+    }
+
+    ElementParserPtr OnServiceNameElement()
+    {
+        return ElementParserPtr(new ServiceNameParser(m_serviceAppInfo));
+    }
+
+    ElementParserPtr OnServiceIconElement()
+    {
+        return ElementParserPtr(new ServiceIconParser(m_serviceAppInfo));
+    }
+
+    ElementParserPtr OnServiceDescriptionElement()
+    {
+        return ElementParserPtr(new ServiceDescriptionParser(m_serviceAppInfo));
+    }
+
+  private:
+    DPL::String m_serviceId;
+    ConfigParserData& m_data;
+    ConfigParserData::ServiceAppInfo m_serviceAppInfo;
+    bool m_autoRestart;
+    bool m_onBoot;
+};
+#endif
+
+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; //ignore unknown according to w3c
+    }
+}
+
+WidgetParser::WidgetParser(ConfigParserData& data) :
+    m_data(data),
+    m_textDirection(Unicode::EMPTY)
+{
+    m_map[L"name"] = std::bind(&WidgetParser::OnNameElement, this);
+    m_map[L"access"] = std::bind(&WidgetParser::OnAccessElement, this);
+    m_map[L"description"] = std::bind(&WidgetParser::OnDescriptionElement, this);
+    m_map[L"author"] = std::bind(&WidgetParser::OnAuthorElement, this);
+    m_map[L"license"] = std::bind(&WidgetParser::OnLicenseElement, this);
+    m_map[L"icon"] = std::bind(&WidgetParser::OnIconElement, this);
+    m_map[L"small-icon"] = std::bind(&WidgetParser::OnSmallIconElement, this);
+    m_map[L"content"] = std::bind(&WidgetParser::OnContentElement, this);
+    m_map[L"preference"] = std::bind(&WidgetParser::OnPreferenceElement, this);
+    m_map[L"setting"] = std::bind(&WidgetParser::OnSettingElement, this);
+    m_map[L"application"] = std::bind(&WidgetParser::OnApplicationElement, this);
+#ifdef IME_ENABLED
+    m_map[L"ime"] = std::bind(&WidgetParser::OnImeElement, this);
+#endif
+#ifdef SERVICE_ENABLED
+    m_map[L"service"] = std::bind(&WidgetParser::OnServiceAppElement, this);
+#endif
+    m_map[L"splash"] = std::bind(&WidgetParser::OnSplashElement, this);
+    m_map[L"background"] = std::bind(&WidgetParser::OnBackgroundElement, this);
+    m_map[L"privilege"] = std::bind(&WidgetParser::OnPrivilegeElement, this);
+    m_map[L"app-control"] = std::bind(&WidgetParser::OnAppControlElement, this);
+    m_map[L"category"] = std::bind(&WidgetParser::OnCategoryElement, this);
+#ifdef DBOX_ENABLED
+    m_map[L"app-widget"] = std::bind(&WidgetParser::OnAppWidgetElement, this);
+#endif
+#if ENABLE(CONTENT_SECURITY_POLICY)
+    m_map[L"content-security-policy"] = std::bind(&WidgetParser::OnCspElement, this);
+    m_map[L"content-security-policy-report-only"] = std::bind(&WidgetParser::OnCspReportOnlyElement, this);
+#endif
+#if ENABLE(ALLOW_NAVIGATION)
+    m_map[L"allow-navigation"] = std::bind(&WidgetParser::OnAllowNavigationElement, this);
+#endif
+    m_map[L"account"] = std::bind(&WidgetParser::OnAccountElement, this);
+    m_map[L"metadata"] = std::bind(&WidgetParser::OnMetadataElement, this);
+}
+
+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::OnSmallIconElement()
+{
+    return ElementParserPtr(new IconParser(m_data, true));
+}
+
+ElementParserPtr WidgetParser::OnContentElement()
+{
+    return ElementParserPtr(new ContentParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnPreferenceElement()
+{
+    return ElementParserPtr(new PreferenceParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnSettingElement()
+{
+    return ElementParserPtr(new SettingParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnApplicationElement()
+{
+    return ElementParserPtr(new ApplicationParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnSplashElement()
+{
+    return ElementParserPtr(new SplashParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnBackgroundElement()
+{
+    return ElementParserPtr(new BackgroundParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnPrivilegeElement()
+{
+    return ElementParserPtr(new PrivilegeParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAppControlElement()
+{
+    return ElementParserPtr(new AppControlParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnCategoryElement()
+{
+    return ElementParserPtr(new CategoryParser(m_data));
+}
+
+#ifdef DBOX_ENABLED
+ElementParserPtr WidgetParser::OnAppWidgetElement()
+{
+    return ElementParserPtr(new AppWidgetParser(m_data));
+}
+#endif
+
+ElementParserPtr WidgetParser::OnCspElement()
+{
+    return ElementParserPtr(new CspParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnCspReportOnlyElement()
+{
+    return ElementParserPtr(new CspReportOnlyParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAllowNavigationElement()
+{
+    return ElementParserPtr(new AllowNavigationParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnAccountElement()
+{
+    return ElementParserPtr(new AccountParser(m_data));
+}
+
+ElementParserPtr WidgetParser::OnMetadataElement()
+{
+    return ElementParserPtr(new MetadataParser(m_data));
+}
+
+#ifdef IME_ENABLED
+ElementParserPtr WidgetParser::OnImeElement()
+{
+    return ElementParserPtr(new ImeParser(m_data));
+}
+#endif
+
+#ifdef SERVICE_ENABLED
+ElementParserPtr WidgetParser::OnServiceAppElement()
+{
+    return ElementParserPtr(new ServiceAppParser(m_data));
+}
+#endif
+
+void WidgetParser::Accept(const Element& element)
+{
+    if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
+        element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
+    {
+        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 {
+            _W("Widget id validation failed: %ls", attribute.value.c_str());
+        }
+    } else if (attribute.name == L"version") {
+        m_version = attribute.value;
+        NormalizeString(m_version);
+    } else if (attribute.name == L"min-version") {
+        _D("min-version attribute was found. Value: %ls", attribute.value.c_str());
+        m_minVersion = attribute.value;
+        NormalizeString(m_minVersion);
+        m_data.minVersionRequired = m_minVersion;
+    } 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 (isdigit(c)) {
+                int val = 0;
+                for (size_t i = 0; i < v.size(); ++i) {
+                    c = v.c_str()[i];
+                    if (isdigit(c)) {
+                        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);
+            std::string dl = DPL::ToUTF8String(*m_defaultlocale);
+
+            if (!LanguageSubtagRstTreeSingleton::Instance().
+                    ValidateLanguageTag(dl)) {
+                _W("Language tag: %s is not valid", dl.c_str());
+                m_defaultlocale = DPL::OptionalString();
+            } else {
+                _D("Default locale found %s", dl.c_str());
+            }
+        } else {
+            _W("Ignoring subsequent default locale");
+        }
+        //Any other value consider as a namespace definition
+    } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
+        _D("Namespace domain: %ls", attribute.name.c_str());
+        _D("Namespace value: %ls", attribute.value.c_str());
+        m_nameSpaces[attribute.name] = attribute.value;
+    }
+    else {
+        _E("Unknown attirbute: namespace=%ls, name=%ls, value=%ls",
+            attribute.ns.c_str(), attribute.name.c_str(), attribute.value.c_str());
+    }
+}
+
+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) {
+        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->second);
+    }
+}
diff --git a/src_wearable/configuration_parser/widget_parser.h b/src_wearable/configuration_parser/widget_parser.h
new file mode 100755 (executable)
index 0000000..13cef2f
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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 <map>
+#include <dpl/foreach.h>
+#include <dpl/optional_typedefs.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 TizenWebAppNamespaceName =
+    L"http://tizen.org/ns/widgets";
+}
+
+namespace PluginsPrefix {
+const char * const W3CPluginsPrefix = "http://www.w3.org/";
+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 OnSmallIconElement();
+    ElementParserPtr OnContentElement();
+    ElementParserPtr OnPreferenceElement();
+    ElementParserPtr OnAccessElement();
+    ElementParserPtr OnSettingElement();
+    ElementParserPtr OnApplicationElement();
+    ElementParserPtr OnSplashElement();
+    ElementParserPtr OnBackgroundElement();
+    ElementParserPtr OnPrivilegeElement();
+    ElementParserPtr OnAppControlElement();
+    ElementParserPtr OnCategoryElement();
+    ElementParserPtr OnAppWidgetElement();
+    ElementParserPtr OnCspElement();
+    ElementParserPtr OnCspReportOnlyElement();
+    ElementParserPtr OnAllowNavigationElement();
+    ElementParserPtr OnAccountElement();
+    ElementParserPtr OnMetadataElement();
+
+#ifdef IME_ENABLED
+    ElementParserPtr OnImeElement();
+#endif
+#ifdef SERVICE_ENABLED
+    ElementParserPtr OnServiceAppElement();
+#endif
+
+    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::OptionalString m_version;
+    DPL::OptionalString m_minVersion;
+    std::list<DPL::String> m_windowModes;
+    DPL::OptionalString m_defaultlocale;
+    std::map<DPL::String, DPL::String> m_nameSpaces;
+};
+
+struct IconParser;
+struct ContentParser;
+
+#endif // WIDGET_PARSER_H_
diff --git a/src_wearable/jobs/job.cpp b/src_wearable/jobs/job.cpp
new file mode 100644 (file)
index 0000000..ec2bb7f
--- /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 <job.h>
+#include <installer_controller.h>
+
+namespace Jobs {
+Job::Job(InstallationType installType) :
+    m_handle(0),
+    m_installationType(installType),
+    m_abortStarted(false),
+    m_paused(false)
+{}
+
+InstallationType Job::GetInstallationType() const
+{
+    return m_installationType;
+}
+
+bool Job::GetAbortStarted() const
+{
+    return m_abortStarted;
+}
+
+void Job::SetAbortStarted(bool flag)
+{
+    m_abortStarted = 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(Logic::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::SendProgressIconPath(const std::string &/*path*/)
+{}
+
+void Job::SaveExceptionData(const Jobs::JobExceptionBase&)
+{}
+} //namespace Jobs
diff --git a/src_wearable/jobs/job.h b/src_wearable/jobs/job.h
new file mode 100644 (file)
index 0000000..3963fc6
--- /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.
+ */
+#ifndef INSTALLER_MODEL_H
+#define INSTALLER_MODEL_H
+
+#include <dpl/mutable_task_list.h>
+
+#include <job_types.h>
+
+namespace Jobs {
+class JobExceptionBase;
+
+typedef int JobHandle;
+
+class Job :
+    public DPL::MutableTaskList
+{
+  public:
+    Job(InstallationType installType);
+
+    InstallationType GetInstallationType() const;
+
+    // Undo
+    void SetAbortStarted(bool flag);
+    bool GetAbortStarted() 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 SendProgressIconPath(const std::string &path);
+
+    virtual void SaveExceptionData(const Jobs::JobExceptionBase&);
+
+  private:
+    JobHandle m_handle;
+    InstallationType m_installationType;
+    bool m_abortStarted;
+    bool m_paused;
+};
+} //namespace Jobs
+
+#endif // INSTALLER_MODEL_H
diff --git a/src_wearable/jobs/job_base.h b/src_wearable/jobs/job_base.h
new file mode 100644 (file)
index 0000000..edcf0f5
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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)) /
+             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;
+    }
+
+  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_wearable/jobs/job_exception_base.h b/src_wearable/jobs/job_exception_base.h
new file mode 100644 (file)
index 0000000..4d35420
--- /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.
+ */
+/**
+ * @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;                                                         \
+    };
+
+#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;                                                  \
+        }                                                                    \
+    };
+
+namespace Jobs {
+DECLARE_JOB_EXCEPTION_BASE(DPL::Exception, JobExceptionBase, 0)
+}
+
+#endif /* SRC_INSTALLER_CORE_JOBS_JOB_EXCEPTION_BASE_H_ */
diff --git a/src_wearable/jobs/job_exception_error.h b/src_wearable/jobs/job_exception_error.h
new file mode 100644 (file)
index 0000000..1caba99
--- /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        job_exception_error.h
+ * @author      Soyoung Kim (sy037.kim@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 JOB_EXCEPTION_ERROR_H
+#define JOB_EXCEPTION_ERROR_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+namespace Jobs {
+namespace Exceptions {
+enum Type
+{
+    Success = 0,                         ///< Success
+
+    /* pkgmgr error */
+    ErrorPackageNotFound,                       ///<
+    ErrorPackageInvalid,                        ///< invalid widget package
+    ErrorPackageLowerVersion,                   ///< given version is lower
+    ErrorPackageExecutableNotFound,
+
+    ErrorManifestNotFound = 11,                 ///<
+    ErrorManifestInvalid,                       ///<
+    ErrorConfigNotFound,                        ///< couldn't find config.xml
+    ErrorConfigInvalid,                         ///< invalid config.xml
+
+    ErrorSignatureNotFound = 21,                ///< signature file not exist.
+    ErrorSignatureInvalid,                      ///< invalid signature file
+    ErrorSignatureVerificationFailed,           ///< failure in verificate
+                                                ///< signature
+    ErrorRootCertificateNotFound = 31,          ///< couldn't find root
+    ErrorCertificationInvaid,                   ///< invalid certification
+    ErrorCertificateChainVerificationFailed,    ///< failure in verificate
+    ErrorCertificateExpired,                    ///< expire cerification.
+
+    ErrorInvalidPrivilege = 41,                 ///< invalid privilege.
+    ErrorPrivilegeLevelViolation,
+
+    ErrorMenuIconNotFound = 51,                 ///<
+
+    ErrorFatalError = 61,                       ///< failure in db operation
+    ErrorOutOfStorage,                          ///< failure in shortage of memory
+    ErrorOutOfMemory,                           ///< failure in shortage of RAM
+    ErrorArgumentInvalid,
+
+    /* wrt-installer error */
+    /* 121-140 : reserved for Web installer */
+    ErrorPackageAlreadyInstalled = 121,     ///< package already in target.
+    ErrorAceCheckFailed,                    ///< failure in ace check.
+    ErrorManifestCreateFailed,              ///< failure in creating manifest
+    ErrorEncryptionFailed,                  ///< failure in encryption resource
+    ErrorInstallOspServcie,                 ///< Failure in installing osp service
+    ErrorPluginInstallationFailed,          ///< failure in plugin installation
+    ErrorWidgetUninstallationFailed,        ///< failure in uninstallation
+    ErrorNotSupportRDSUpdate,               ///< failure in rds update
+
+    ErrorUnknown = 140,                     ///< do not use this error code.
+};
+}
+}
+
+#endif /* JOB_EXCEPTION_ERROR_H */
diff --git a/src_wearable/jobs/job_types.h b/src_wearable/jobs/job_types.h
new file mode 100644 (file)
index 0000000..5f845bf
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2013 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_types.h
+ * @author  Tomasz Iwanek ()
+ */
+#ifndef JOB_TYPES_H
+#define JOB_TYPES_H
+
+namespace Jobs {
+/**
+ * @brief Defines installation and uninstallation type.
+ */
+enum InstallationType
+{
+    UnknownInstallation,  ///< defines installation of yet unknown type
+    NewInstallation,      ///< defines install process
+    UpdateInstallation,   ///< defines update installation
+    Uninstallation,       ///< defines uninstall process
+    PluginInstallation    ///< defines plugin installation process
+};
+
+}
+
+#endif // JOB_TYPES_H
diff --git a/src_wearable/jobs/plugin_install/job_plugin_install.cpp b/src_wearable/jobs/plugin_install/job_plugin_install.cpp
new file mode 100755 (executable)
index 0000000..36a5d83
--- /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    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 "plugin_objects.h"
+#include <wrt_common_types.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace PluginInstall {
+JobPluginInstall::JobPluginInstall(PluginPath const &pluginPath,
+                                   const PluginInstallerStruct &installerStruct)
+    :
+    Job(PluginInstallation),
+    JobContextBase<PluginInstallerStruct>(installerStruct),
+    m_exceptionCaught(Jobs::Exceptions::Success)
+{
+    //
+    // 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) {
+        _D("Call Plugin install progressCallback");
+        GetInstallerStruct().progressCallback(GetInstallerStruct().userParam,
+                                              GetProgressPercent(),
+                                              GetProgressDescription());
+    }
+}
+
+void JobPluginInstall::SendFinishedSuccess()
+{
+    PluginHandle handle = getNewPluginHandle();
+
+    if (handle != Jobs::PluginInstall::JobPluginInstall::INVALID_HANDLE &&
+        isReadyToInstall())
+    {
+        _D("Call Plugin install success finishedCallback");
+        GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                              Jobs::Exceptions::Success);
+    } else {
+        _D("Call Plugin install waiting finishedCallback");
+        GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                              Jobs::Exceptions::ErrorPluginInstallationFailed);
+
+        _D("Installation: %s NOT possible", getFilePath().c_str());
+    }
+}
+
+void JobPluginInstall::SendFinishedFailure()
+{
+    LOGE(COLOR_ERROR "Error in plugin installation step: %d" COLOR_END, m_exceptionCaught);
+    LOGE(COLOR_ERROR "Message: %s" COLOR_END, m_exceptionMessage.c_str());
+    fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
+
+    _D("Call Plugin install failure finishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          m_exceptionCaught);
+}
+
+void JobPluginInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
+{
+    m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
+    m_exceptionMessage = e.GetMessage();
+}
+} //namespace Jobs
+} //namespace PluginInstall
diff --git a/src_wearable/jobs/plugin_install/job_plugin_install.h b/src_wearable/jobs/plugin_install/job_plugin_install.h
new file mode 100644 (file)
index 0000000..a8d3386
--- /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    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(PluginPath const &pluginPath,
+                     const PluginInstallerStruct &installerStruct);
+
+    WrtDB::DbPluginHandle getNewPluginHandle() const
+    {
+        return m_context.pluginHandle;
+    }
+    std::string getFilePath() const
+    {
+        return m_context.pluginFilePath.Fullpath();
+    }
+    bool isReadyToInstall() const
+    {
+        return m_context.installationCompleted;
+    }
+
+    void SendProgress();
+    void SendFinishedSuccess();
+    void SendFinishedFailure();
+    void SaveExceptionData(const Jobs::JobExceptionBase &e);
+
+  private:
+   PluginInstallerContext m_context;
+
+    //TODO move it to base class of all jobs
+    //maybe separate JobBase class for this?
+    Jobs::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_wearable/jobs/plugin_install/plugin_install_task.cpp b/src_wearable/jobs/plugin_install/plugin_install_task.cpp
new file mode 100644 (file)
index 0000000..5f42730
--- /dev/null
@@ -0,0 +1,389 @@
+/*
+ * 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/foreach.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"
+#include <wrt_plugin_export.h>
+#include <plugin_path.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+#define SET_PLUGIN_INSTALL_PROGRESS(step, desc)              \
+    m_context->installerTask->UpdateProgress(               \
+        PluginInstallerContext::step, desc);
+
+#define DISABLE_IF_PLUGIN_WITHOUT_LIB()        \
+    if (m_pluginInfo.m_libraryName.empty()) \
+    {                                          \
+        _W("Plugin without library."); \
+        return;                                \
+    }
+
+namespace Jobs {
+namespace PluginInstall {
+PluginInstallTask::PluginInstallTask(PluginInstallerContext *inCont) :
+    DPL::TaskDecl<PluginInstallTask>(this),
+    m_context(inCont),
+    m_pluginHandle(0),
+    m_dataFromConfigXML(true)
+{
+    AddStep(&PluginInstallTask::stepCheckPluginPath);
+    AddStep(&PluginInstallTask::stepParseConfigFile);
+    AddStep(&PluginInstallTask::stepFindPluginLibrary);
+    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()
+{
+    _D("Plugin installation: step CheckPluginPath");
+
+    if(!m_context->pluginFilePath.Exists()){
+        ThrowMsg(Exceptions::PluginPathFailed,
+                 "No such path");
+    }
+
+    SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Path to plugin verified");
+}
+
+void PluginInstallTask::stepParseConfigFile()
+{
+    _D("Plugin installation: step parse config file");
+
+    if(!m_context->pluginFilePath.getMetaFile().Exists()){
+        m_dataFromConfigXML = false;
+        return;
+    }
+
+    _D("Plugin Config file::%s", m_context->pluginFilePath.getMetaFile().Fullpath().c_str());
+
+    Try
+    {
+        PluginMetafileReader reader;
+        reader.initialize(m_context->pluginFilePath.getMetaFile());
+        reader.read(m_pluginInfo);
+
+        FOREACH(it, m_pluginInfo.m_featureContainer)
+        {
+            _D("Parsed feature : %s", it->m_name.c_str());
+            FOREACH(devCap, it->m_deviceCapabilities) {
+                _D("  |  DevCap : %s", (*devCap).c_str());
+            }
+        }
+
+        SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Config file analyzed");
+    }
+    Catch(ValidationCore::ParserSchemaException::Base)
+    {
+        _E("Error during file processing %s", m_context->pluginFilePath.getMetaFile().Fullpath().c_str());
+        ThrowMsg(Exceptions::PluginMetafileFailed,
+                 "Metafile error");
+    }
+}
+
+void PluginInstallTask::stepFindPluginLibrary()
+{
+    if (m_dataFromConfigXML) {
+        return;
+    }
+    _D("Plugin installation: step find plugin library");
+    _D("Plugin .so: %s", m_context->pluginFilePath.getLibraryName().c_str());
+    m_pluginInfo.m_libraryName = m_context->pluginFilePath.getLibraryName();
+}
+
+void PluginInstallTask::stepCheckIfAlreadyInstalled()
+{
+    if (PluginDAO::isPluginInstalled(m_pluginInfo.m_libraryName)) {
+        ThrowMsg(Exceptions::PluginAlreadyInstalled,
+                 "Plugin already installed");
+    }
+
+    SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_EXISTS_CHECK, "Check if plugin exist");
+}
+
+void PluginInstallTask::stepLoadPluginLibrary()
+{
+    _D("Plugin installation: step load library");
+
+    DISABLE_IF_PLUGIN_WITHOUT_LIB()
+
+    _D("Loading plugin: %s", m_context->pluginFilePath.getLibraryName().c_str());
+
+    fprintf(stderr, " - Try to dlopen() : [%s] ", m_context->pluginFilePath.getLibraryPath().Fullpath().c_str());
+
+    void *dlHandle = dlopen( m_context->pluginFilePath.getLibraryPath().Fullpath().c_str(), RTLD_LAZY);
+    if (dlHandle == NULL) {
+        const char* error = (const char*)dlerror();
+        fprintf(stderr,
+                "-> Failed!\n   %s\n",
+                (error != NULL ? error : "unknown"));
+        _E("Failed to load plugin: %s. Reason: %s",
+            m_context->pluginFilePath.getLibraryName().c_str(), (error != NULL ? error : "unknown"));
+        ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+    }
+
+    fprintf(stderr, "-> Done.\n");
+
+    const js_entity_definition_t *rawEntityList = NULL;
+    get_widget_entity_map_proc *getWidgetEntityMapProcPtr = NULL;
+
+    getWidgetEntityMapProcPtr =
+        reinterpret_cast<get_widget_entity_map_proc *>(dlsym(dlHandle,
+                                                             PLUGIN_GET_CLASS_MAP_PROC_NAME));
+
+    if (getWidgetEntityMapProcPtr) {
+        rawEntityList = (*getWidgetEntityMapProcPtr)();
+    } else {
+        rawEntityList =
+            static_cast<const js_entity_definition_t *>(dlsym(dlHandle,
+                                                              PLUGIN_CLASS_MAP_NAME));
+    }
+
+    if (rawEntityList == NULL) {
+        dlclose(dlHandle);
+        _E("Failed to read class name %s", m_context->pluginFilePath.getLibraryName().c_str());
+        ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+    }
+
+    if (!m_dataFromConfigXML) {
+        on_widget_init_proc *onWidgetInitProc =
+            reinterpret_cast<on_widget_init_proc *>(
+                dlsym(dlHandle, PLUGIN_WIDGET_INIT_PROC_NAME));
+
+        if (NULL == onWidgetInitProc) {
+            dlclose(dlHandle);
+            _E("Failed to read onWidgetInit symbol %s", m_context->pluginFilePath.getLibraryName().c_str());
+            ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+        }
+
+        // obtain feature -> dev-cap mapping
+        feature_mapping_interface_t mappingInterface = { NULL, NULL, NULL };
+        (*onWidgetInitProc)(&mappingInterface);
+
+        if (!mappingInterface.featGetter || !mappingInterface.release ||
+            !mappingInterface.dcGetter)
+        {
+            _E("Failed to obtain mapping interface from .so");
+            ThrowMsg(Exceptions::PluginLibraryError, "Library error");
+        }
+
+        feature_mapping_t* devcapMapping = mappingInterface.featGetter();
+
+        _D("Getting mapping from features to device capabilities");
+
+        for (size_t i = 0; i < devcapMapping->featuresCount; ++i) {
+            PluginMetafileData::Feature feature;
+            feature.m_name = devcapMapping->features[i].feature_name;
+
+            _D("Feature: %s", feature.m_name.c_str());
+
+            const devcaps_t* dc =
+                mappingInterface.dcGetter(
+                    devcapMapping,
+                    devcapMapping->features[i].
+                        feature_name);
+
+            if (dc) {
+                _D("devcaps count: %d", dc->devCapsCount);
+
+                for (size_t j = 0; j < dc->devCapsCount; ++j) {
+                    _D("devcap: %s", dc->deviceCaps[j]);
+                    feature.m_deviceCapabilities.insert(dc->deviceCaps[j]);
+                }
+            }
+
+            m_pluginInfo.m_featureContainer.insert(feature);
+        }
+
+        mappingInterface.release(devcapMapping);
+    }
+
+    m_libraryObjects = PluginObjectsPtr(new PluginObjects());
+    const js_entity_definition_t *rawEntityListIterator = rawEntityList;
+
+    _D("#####");
+    _D("##### Plugin: %s supports new plugin API",
+        m_context->pluginFilePath.getLibraryName().c_str());
+    _D("#####");
+
+    while (rawEntityListIterator->parent_name != NULL &&
+           rawEntityListIterator->object_name != NULL)
+    {
+        _D("#####     [%s]: ", rawEntityListIterator->object_name);
+        _D("#####     Parent: %s", rawEntityListIterator->parent_name);
+        _D("#####");
+
+        m_libraryObjects->addObjects(rawEntityListIterator->parent_name,
+                                     rawEntityListIterator->object_name);
+
+        ++rawEntityListIterator;
+    }
+
+    // Unload library
+    if (dlclose(dlHandle) != 0) {
+        _E("Cannot close plugin handle");
+    } else {
+        _D("Library is unloaded");
+    }
+
+    // Load export table
+    _D("Library successfuly loaded and parsed");
+
+    SET_PLUGIN_INSTALL_PROGRESS(LOADING_LIBRARY, "Library loaded and analyzed");
+}
+
+void PluginInstallTask::stepRegisterPlugin()
+{
+    _D("Plugin installation: step register Plugin");
+
+    m_pluginHandle =
+        PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath.Fullpath());
+
+    SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered");
+}
+
+void PluginInstallTask::stepRegisterFeatures()
+{
+    _D("Plugin installation: step register features");
+
+    FOREACH(it, m_pluginInfo.m_featureContainer)
+    {
+        _D("PluginHandle: %d", m_pluginHandle);
+        FeatureDAO::RegisterFeature(*it, m_pluginHandle);
+    }
+    SET_PLUGIN_INSTALL_PROGRESS(REGISTER_FEATURES, "Features registered");
+}
+
+void PluginInstallTask::stepRegisterPluginObjects()
+{
+    _D("Plugin installation: step register objects");
+
+    DISABLE_IF_PLUGIN_WITHOUT_LIB()
+
+    //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)) {
+            _D("Dependency from the same library. ignored");
+            continue;
+        }
+
+        PluginDAO::registerPluginRequiredObject(*it, m_pluginHandle);
+    }
+
+    SET_PLUGIN_INSTALL_PROGRESS(REGISTER_OBJECTS, "Plugin Objects registered");
+}
+
+void PluginInstallTask::stepResolvePluginDependencies()
+{
+    _D("Plugin installation: step resolve dependencies ");
+
+    //DISABLE_IF_PLUGIN_WITHOUT_LIB
+    if (m_pluginInfo.m_libraryName.empty()) {
+        PluginDAO::setPluginInstallationStatus(
+            m_pluginHandle,
+            PluginDAO::
+                INSTALLATION_COMPLETED);
+        //Installation completed
+        m_context->pluginHandle = m_pluginHandle;
+        m_context->installationCompleted = true;
+        _W("Plugin without library.");
+        return;
+    }
+
+    PluginHandleSetPtr handles = PluginHandleSetPtr(new PluginHandleSet);
+
+    DbPluginHandle handle = INVALID_PLUGIN_HANDLE;
+
+    //register requiredObjects
+    FOREACH(it, *(m_libraryObjects->getDependentObjects()))
+    {
+        if (m_libraryObjects->hasObject(*it)) {
+            _D("Dependency from the same library. ignored");
+            continue;
+        }
+
+        handle = PluginDAO::getPluginHandleForImplementedObject(*it);
+        if (handle == INVALID_PLUGIN_HANDLE) {
+            _E("Library implementing: %s NOT FOUND", (*it).c_str());
+            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_wearable/jobs/plugin_install/plugin_install_task.h b/src_wearable/jobs/plugin_install/plugin_install_task.h
new file mode 100644 (file)
index 0000000..c7a5d8c
--- /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    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_pluginInfo;
+
+    //Plugin LibraryObjects
+    PluginObjectsPtr m_libraryObjects;
+
+    WrtDB::DbPluginHandle m_pluginHandle;
+
+    bool m_dataFromConfigXML;
+
+    //steps
+    void stepCheckPluginPath();
+    void stepFindPluginLibrary();
+    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_wearable/jobs/plugin_install/plugin_installer_context.h b/src_wearable/jobs/plugin_install/plugin_installer_context.h
new file mode 100644 (file)
index 0000000..1efd504
--- /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_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_path.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
+    };
+
+    PluginPath pluginFilePath;           ///< plugin directory
+    PluginPath metaFilePath;
+    bool m_dataFromConfigXML;
+    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_wearable/jobs/plugin_install/plugin_installer_errors.h b/src_wearable/jobs/plugin_install/plugin_installer_errors.h
new file mode 100644 (file)
index 0000000..11c7f88
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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>
+#include <job_exception_error.h>
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace PluginInstall {
+namespace Exceptions {
+
+DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown)
+DECLARE_JOB_EXCEPTION(Base, PluginPathFailed, ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PluginMetafileFailed, ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PluginAlreadyInstalled,
+        ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PluginLibraryError, ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, InstallationWaitingError,
+        ErrorPluginInstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, UnknownError, ErrorUnknown)
+} //namespace
+} //namespace
+} //namespace
+
+#endif
+//WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_INSTALLER_ERRORS_H_
+
diff --git a/src_wearable/jobs/plugin_install/plugin_installer_struct.h b/src_wearable/jobs/plugin_install/plugin_installer_struct.h
new file mode 100644 (file)
index 0000000..c253897
--- /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::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_wearable/jobs/plugin_install/plugin_metafile_reader.cpp b/src_wearable/jobs/plugin_install/plugin_metafile_reader.cpp
new file mode 100644 (file)
index 0000000..c7df516
--- /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.
+ */
+/**
+ * @file        plugin_metafile_reader.cpp
+ * @author      Grzegorz Krawczyk(g.krawczyk@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+
+#include "plugin_metafile_reader.h"
+#include <plugin_path.h>
+
+using namespace WrtDB;
+
+namespace {
+const std::string XML_NAMESPACE = "";
+
+const std::string TOKEN_LIBRARY_NAME = "library-name";
+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_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::initialize(const PluginPath &filename)
+{
+    m_parserSchema.initialize(filename.Fullpath(),
+                              true,
+                              ValidationCore::SaxReader::VALIDATION_DTD,
+                              std::string());
+}
+
+void PluginMetafileReader::read(WrtDB::PluginMetafileData &data)
+{
+    m_parserSchema.read(data);
+}
+
+void PluginMetafileReader::blankFunction(PluginMetafileData & /* data */)
+{}
+
+void PluginMetafileReader::tokenEndLibraryName(PluginMetafileData &data)
+{
+    data.m_libraryName = m_parserSchema.getText();
+}
+
+void PluginMetafileReader::tokenEndApiFeature(PluginMetafileData &data)
+{
+    data.m_featureContainer.insert(m_feature);
+    m_feature.m_deviceCapabilities.clear();
+}
+
+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_wearable/jobs/plugin_install/plugin_metafile_reader.h b/src_wearable/jobs/plugin_install/plugin_metafile_reader.h
new file mode 100644 (file)
index 0000000..a3a3068
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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 PluginPath;
+
+class PluginMetafileReader
+{
+  public:
+    PluginMetafileReader();
+
+    void initialize(const PluginPath &filename);
+
+    void read(WrtDB::PluginMetafileData &data);
+
+  private:
+    void blankFunction(WrtDB::PluginMetafileData &data);
+
+    void tokenEndLibraryName(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_wearable/jobs/plugin_install/plugin_objects.cpp b/src_wearable/jobs/plugin_install/plugin_objects.cpp
new file mode 100644 (file)
index 0000000..9235f47
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * 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 <installer_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()) {
+        _E("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()) {
+        _E("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_wearable/jobs/plugin_install/plugin_objects.h b/src_wearable/jobs/plugin_install/plugin_objects.h
new file mode 100644 (file)
index 0000000..0b27a14
--- /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        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 <memory>
+#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 std::shared_ptr<PluginObjects> PluginObjectsPtr;
+
+#endif
diff --git a/src_wearable/jobs/widget_install/ace_registration.cpp b/src_wearable/jobs/widget_install/ace_registration.cpp
new file mode 100644 (file)
index 0000000..31df490
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2012 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_registration.cpp
+ * @author  Andrzej Surdej (a.surdej@gmail.com)
+ * @version 1.0
+ * @brief   Translate structures to ace api - implementation file
+ */
+
+#include <ace_registration.h>
+#include <dpl/foreach.h>
+#include <dpl/optional_typedefs.h>
+#include <ace_api_install.h>
+
+#include <installer_log.h>
+
+namespace {
+char* toAceString(const DPL::OptionalString& os)
+{
+    if (!!os) {
+        return strdup(DPL::ToUTF8String(*os).c_str());
+    } else {
+        return NULL;
+    }
+}
+
+char* toAceString(const std::string& str)
+{
+    if (!str.empty()) {
+        return strdup(str.c_str());
+    } else {
+        return NULL;
+    }
+}
+} //anonymous namespace
+
+namespace AceApi {
+bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle,
+                       const WrtDB::WidgetRegisterInfo& widgetConfig,
+                       const WrtDB::WidgetCertificateDataList& certList)
+{
+    _D("Updating Ace database");
+    struct widget_info wi;
+
+    switch (widgetConfig.webAppType.appType) {
+    case WrtDB::APP_TYPE_TIZENWEBAPP:
+        wi.type = Tizen;
+        break;
+    default:
+        _E("Unknown application type");
+        return false;
+    }
+
+    wi.id = toAceString(widgetConfig.configInfo.widget_id);
+    wi.version = toAceString(widgetConfig.configInfo.version);
+    wi.author = toAceString(widgetConfig.configInfo.authorName);
+    // TODO: Need to remove "shareHref" from "widget_info" in wrt-security
+    wi.shareHerf = NULL;
+    _D("Basic data converted. Certificates begin.");
+
+    //one more element for NULL termination
+    _D("Found: %d certificates", certList.size());
+    ace_certificate_data** certData = new ace_certificate_data *
+        [certList.size() + 1];
+    certData[certList.size()] = NULL; // last element set to NULL
+
+    int i = 0;
+    FOREACH(it, certList)
+    {
+        certData[i] = new ace_certificate_data;
+        switch (it->owner) {
+        case WrtDB::WidgetCertificateData::AUTHOR:
+            certData[i]->owner = AUTHOR;
+            break;
+        case WrtDB::WidgetCertificateData::DISTRIBUTOR:
+            certData[i]->owner = DISTRIBUTOR;
+            break;
+        default:
+            _D("Unknown owner type of cert");
+            certData[i]->owner = UNKNOWN;
+            break;
+        }
+        switch (it->type) {
+        case WrtDB::WidgetCertificateData::ENDENTITY:
+            certData[i]->type = ENDENTITY;
+            break;
+        case WrtDB::WidgetCertificateData::ROOT:
+            certData[i]->type = ROOT;
+            break;
+        default:
+            _E("Unknown type of cert");
+            certData[i]->type = ENDENTITY;
+            break;
+        }
+        certData[i]->chain_id = it->chainId;
+
+        certData[i]->md5_fp = toAceString(it->strMD5Fingerprint);
+        certData[i]->sha1_fp = toAceString(it->strSHA1Fingerprint);
+        certData[i]->common_name =
+            toAceString(DPL::ToUTF8String(it->strCommonName));
+        ++i;
+    }
+
+    _D("Registerign widget in ace");
+    ace_return_t retval = ace_register_widget(
+            static_cast<ace_widget_handle_t>(widgetHandle), &wi, certData);
+
+    //clean up - WidgetInfo
+    free(wi.author);
+    free(wi.id);
+    free(wi.version);
+
+    //free cert list
+    i = 0;
+    while (certData[i] != NULL) {
+        free(certData[i]->common_name);
+        free(certData[i]->md5_fp);
+        free(certData[i]->sha1_fp);
+        delete certData[i];
+        ++i;
+    }
+    delete[] certData;
+    return retval == ACE_OK;
+}
+bool registerAceWidgetFromDB(const WrtDB::DbWidgetHandle& widgetHandle)
+{
+    using namespace WrtDB;
+    _D("Updating Ace database from Widget DB");
+    struct widget_info wi;
+    DPL::OptionalString os;
+    WrtDB::WidgetCertificateDataList certList;
+
+    wi.id = NULL;
+    wi.version = NULL;
+    wi.author = NULL;
+    wi.shareHerf = NULL;
+
+    Try {
+        WidgetDAOReadOnly dao(widgetHandle);
+
+        WidgetType type = dao.getWidgetType();
+        if (type == WrtDB::APP_TYPE_TIZENWEBAPP) {
+            wi.type = Tizen;
+        } else {
+            _E("Unknown application type");
+            return false;
+        }
+
+        wi.id = toAceString(dao.getGUID());
+        wi.version = toAceString(dao.getVersion());
+        wi.author = toAceString(dao.getAuthorName());
+        // TODO: Need to remove "shareHref" from "widget_info" in wrt-security
+        wi.shareHerf = NULL;
+        _D("Basic data converted. Certificates begin.");
+        certList = dao.getCertificateDataList();
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        _E("Widget does not exist");
+        if(wi.id != NULL) {
+            free(wi.id);
+        }
+        if(wi.version != NULL) {
+            free(wi.version);
+        }
+        if(wi.author != NULL) {
+            free(wi.author);
+        }
+        if(wi.shareHerf != NULL) {
+            free(wi.shareHerf);
+        }
+        return false;
+    }
+
+    //one more element for NULL termination
+    _D("Found: %d certificates", certList.size());
+    ace_certificate_data** certData = new ace_certificate_data *
+        [certList.size() + 1];
+    certData[certList.size()] = NULL; // last element set to NULL
+
+    int i = 0;
+    FOREACH(it, certList)
+    {
+        certData[i] = new ace_certificate_data;
+        switch (it->owner) {
+        case WrtDB::WidgetCertificateData::AUTHOR:
+            certData[i]->owner = AUTHOR;
+            break;
+        case WrtDB::WidgetCertificateData::DISTRIBUTOR:
+            certData[i]->owner = DISTRIBUTOR;
+            break;
+        default:
+            _D("Unknown owner type of cert");
+            certData[i]->owner = UNKNOWN;
+            break;
+        }
+        switch (it->type) {
+        case WrtDB::WidgetCertificateData::ENDENTITY:
+            certData[i]->type = ENDENTITY;
+            break;
+        case WrtDB::WidgetCertificateData::ROOT:
+            certData[i]->type = ROOT;
+            break;
+        default:
+            _E("Unknown type of cert");
+            certData[i]->type = ENDENTITY;
+            break;
+        }
+        certData[i]->chain_id = it->chainId;
+
+        certData[i]->md5_fp = toAceString(it->strMD5Fingerprint);
+        certData[i]->sha1_fp = toAceString(it->strSHA1Fingerprint);
+        certData[i]->common_name =
+            toAceString(DPL::ToUTF8String(it->strCommonName));
+        ++i;
+    }
+
+    _D("Registerign widget in ace");
+    ace_return_t retval = ace_register_widget(
+            static_cast<ace_widget_handle_t>(widgetHandle), &wi, certData);
+
+    //clean up - WidgetInfo
+    free(wi.author);
+    free(wi.id);
+    free(wi.version);
+
+    //free cert list
+    i = 0;
+    while (certData[i] != NULL) {
+        free(certData[i]->common_name);
+        free(certData[i]->md5_fp);
+        free(certData[i]->sha1_fp);
+        delete certData[i];
+        ++i;
+    }
+    delete[] certData;
+    return retval == ACE_OK;
+}
+}
diff --git a/src_wearable/jobs/widget_install/ace_registration.h b/src_wearable/jobs/widget_install/ace_registration.h
new file mode 100644 (file)
index 0000000..f98c3ce
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 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_registration.h
+ * @author  Andrzej Surdej (a.surdej@gmail.com)
+ * @version 1.0
+ * @brief   Translate structures to ace api - header file
+ */
+#ifndef WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_
+#define WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+namespace AceApi {
+bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle,
+                       const WrtDB::WidgetRegisterInfo& widgetConfig,
+                       const WrtDB::WidgetCertificateDataList& certList);
+bool registerAceWidgetFromDB(const WrtDB::DbWidgetHandle& widgetHandle);
+}
+
+#endif  /* WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_ */
+
diff --git a/src_wearable/jobs/widget_install/directory_api.cpp b/src_wearable/jobs/widget_install/directory_api.cpp
new file mode 100644 (file)
index 0000000..63532ec
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 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    directory_api.cpp
+ * @author  Soyoung Kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   directory api - implementation file
+ */
+
+#include <cerrno>
+#include <directory_api.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fstream>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/errno_string.h>
+#include <installer_log.h>
+
+namespace DirectoryApi {
+bool DirectoryCopy(std::string source, std::string dest)
+{
+    DIR* dir = opendir(source.c_str());
+    if (NULL == dir) {
+        return false;
+    }
+
+    struct dirent dEntry;
+    struct dirent *dEntryResult;
+    int return_code;
+
+    do {
+        struct stat statInfo;
+        return_code = readdir_r(dir, &dEntry, &dEntryResult);
+        if (dEntryResult != NULL && return_code == 0) {
+            std::string fileName = dEntry.d_name;
+            std::string fullName = source + "/" + fileName;
+
+            if (stat(fullName.c_str(), &statInfo) != 0) {
+                closedir(dir);
+                return false;
+            }
+
+            if (S_ISDIR(statInfo.st_mode)) {
+                if (("." == fileName) || (".." == fileName)) {
+                    continue;
+                }
+                std::string destFolder = dest + "/" + fileName;
+                WrtUtilMakeDir(destFolder);
+
+                if (!DirectoryCopy(fullName, destFolder)) {
+                    closedir(dir);
+                    return false;
+                }
+            }
+
+            std::string destFile = dest + "/" + fileName;
+            std::ifstream infile(fullName);
+            std::ofstream outfile(destFile);
+            outfile << infile.rdbuf();
+            outfile.close();
+            infile.close();
+
+            errno = 0;
+            if (-1 == chown(destFile.c_str(),
+                            statInfo.st_uid,
+                            statInfo.st_gid)) {
+                int error = errno;
+                _D("Failed to change owner [%s]", DPL::GetErrnoString(error).c_str());
+            }
+        }
+    } while (dEntryResult != NULL && return_code == 0);
+    closedir(dir);
+    return true;
+}
+}
diff --git a/src_wearable/jobs/widget_install/directory_api.h b/src_wearable/jobs/widget_install/directory_api.h
new file mode 100644 (file)
index 0000000..1632528
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 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    directory_api.h
+ * @author  Soyoung Kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   directory api - header file
+ */
+#ifndef WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_
+#define WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_
+
+#include<string>
+
+namespace DirectoryApi {
+bool DirectoryCopy(std::string source, std::string dest);
+}
+
+#endif  /* WRT_SRC_INSTALLER_CORE_DIRECTORY_API_H_ */
+
diff --git a/src_wearable/jobs/widget_install/job_widget_install.cpp b/src_wearable/jobs/widget_install/job_widget_install.cpp
new file mode 100644 (file)
index 0000000..14e01c5
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * 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 <string>
+#include <sys/time.h>
+#include <ctime>
+#include <cstdlib>
+#include <limits.h>
+#include <regex.h>
+
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <dpl/localization/w3c_file_localization.h>
+
+#include <pkg-manager/pkgmgr_signal.h>
+#include <app_manager.h>
+
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_certify.h>
+#include <widget_install/task_certify_level.h>
+#include <widget_install/task_process_config.h>
+#include <widget_install/task_file_manipulation.h>
+#include <widget_install/task_ace_check.h>
+#include <widget_install/task_smack.h>
+#include <widget_install/task_manifest_file.h>
+#include <widget_install/task_prepare_files.h>
+#include <widget_install/task_recovery.h>
+#include <widget_install/task_install_ospsvc.h>
+#include <widget_install/task_update_files.h>
+#include <widget_install/task_database.h>
+#include <widget_install/task_remove_backup.h>
+#include <widget_install/task_encrypt_resource.h>
+#include <widget_install/task_pkg_info_update.h>
+#include <widget_install/task_commons.h>
+#include <widget_install/task_prepare_reinstall.h>
+#include <widget_install/task_configuration.h>
+#include <widget_install/task_user_data_manipulation.h>
+#include <widget_install/task_status_check.h>
+
+#include <widget_install_to_external.h>
+#include <widget_install/widget_unzip.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+JobWidgetInstall::JobWidgetInstall(
+    std::string const &widgetPath,
+    std::string const &tzPkgId,
+    const Jobs::WidgetInstall::WidgetInstallationStruct &
+    installerStruct) :
+    Job(UnknownInstallation),
+    JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct>(installerStruct),
+    m_exceptionCaught(Jobs::Exceptions::Success)
+{
+    m_installerContext.mode = m_jobStruct.m_installMode;
+    m_installerContext.requestedPath = widgetPath;
+    m_jobStruct.pkgmgrInterface->setPkgname(tzPkgId);
+
+    if (InstallMode::Command::RECOVERY == m_installerContext.mode.command) {
+        m_installerContext.widgetConfig.tzPkgid = DPL::FromUTF8String(tzPkgId);
+        AddTask(new TaskRecovery(m_installerContext));
+    }
+
+    //start configuration of installation
+    AddTask(new TaskConfiguration(m_installerContext));
+
+    // Init installer context
+    m_installerContext.installStep = InstallerContext::INSTALL_START;
+    m_installerContext.job = this;
+
+    m_installerContext.callerPkgId
+            = DPL::FromUTF8String(m_jobStruct.pkgmgrInterface->getCallerId());
+    _D("Caller Package Id : %s", DPL::ToUTF8String(m_installerContext.callerPkgId).c_str());
+}
+
+void JobWidgetInstall::appendNewInstallationTaskList()
+{
+    _D("Configure installation succeeded");
+    m_installerContext.job->SetProgressFlag(true);
+
+    AddTask(new TaskFileManipulation(m_installerContext));
+    AddTask(new TaskProcessConfig(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+    {
+        AddTask(new TaskPrepareFiles(m_installerContext));
+    }
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskUserDataManipulation(m_installerContext));
+    if (m_installerContext.needEncryption) {
+        AddTask(new TaskEncryptResource(m_installerContext));
+    }
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP) {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+    AddTask(new TaskDatabase(m_installerContext));
+    AddTask(new TaskAceCheck(m_installerContext));
+    AddTask(new TaskSmack(m_installerContext));
+    AddTask(new TaskPkgInfoUpdate(m_installerContext));
+}
+
+void JobWidgetInstall::appendUpdateInstallationTaskList()
+{
+    _D("Configure installation updated");
+    _D("Widget Update");
+    m_installerContext.job->SetProgressFlag(true);
+    AddTask(new TaskStatusCheck(m_installerContext));
+
+    if (m_installerContext.mode.command ==
+        InstallMode::Command::REINSTALL) {
+        AddTask(new TaskPrepareReinstall(m_installerContext));
+    }
+
+    if (m_installerContext.mode.extension !=
+            InstallMode::ExtensionType::DIR) {
+        AddTask(new TaskUpdateFiles(m_installerContext));
+        AddTask(new TaskFileManipulation(m_installerContext));
+    }
+
+    AddTask(new TaskProcessConfig(m_installerContext));
+
+    if (m_installerContext.widgetConfig.packagingType ==
+        WrtDB::PKG_TYPE_HOSTED_WEB_APP) {
+        AddTask(new TaskPrepareFiles(m_installerContext));
+    }
+
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskUserDataManipulation(m_installerContext));
+    if (m_installerContext.needEncryption) {
+        AddTask(new TaskEncryptResource(m_installerContext));
+    }
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP) {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+
+    AddTask(new TaskDatabase(m_installerContext));
+    AddTask(new TaskAceCheck(m_installerContext));
+    //TODO: remove widgetHandle from this task and move before database task
+    // by now widget handle is needed in ace check
+    // Any error in acecheck while update will break widget
+    AddTask(new TaskSmack(m_installerContext));
+    AddTask(new TaskRemoveBackupFiles(m_installerContext));
+    AddTask(new TaskPkgInfoUpdate(m_installerContext));
+}
+
+void JobWidgetInstall::appendRDSUpdateTaskList()
+{
+    _D("Configure installation RDS updated");
+    m_installerContext.job->SetProgressFlag(true);
+    AddTask(new TaskStatusCheck(m_installerContext));
+    AddTask(new TaskPrepareReinstall(m_installerContext));
+    AddTask(new TaskCertify(m_installerContext));
+}
+
+void JobWidgetInstall::appendRecoveryTaskList()
+{
+    _D("Recovery Task");
+    m_installerContext.job->SetProgressFlag(true);
+
+    AddTask(new TaskProcessConfig(m_installerContext));
+
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP) {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+    AddTask(new TaskSmack(m_installerContext));
+}
+
+void JobWidgetInstall::appendFotaInstallationTaskList()
+{
+    /* TODO */
+    _D("Configure installation succeeded");
+    m_installerContext.job->SetProgressFlag(true);
+
+    AddTask(new TaskProcessConfig(m_installerContext));
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskUserDataManipulation(m_installerContext));
+    if (m_installerContext.needEncryption) {
+        AddTask(new TaskEncryptResource(m_installerContext));
+    }
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP)
+    {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+    AddTask(new TaskDatabase(m_installerContext));
+    AddTask(new TaskAceCheck(m_installerContext));
+    AddTask(new TaskSmack(m_installerContext));
+    AddTask(new TaskRemoveBackupFiles(m_installerContext));
+    AddTask(new TaskPkgInfoUpdate(m_installerContext));
+}
+
+void JobWidgetInstall::appendFotaUpdateTaskList()
+{
+    _D("Configure installation updated");
+    _D("Widget Update");
+    m_installerContext.job->SetProgressFlag(true);
+
+    AddTask(new TaskProcessConfig(m_installerContext));
+    AddTask(new TaskCertify(m_installerContext));
+    AddTask(new TaskCertifyLevel(m_installerContext));
+    AddTask(new TaskUserDataManipulation(m_installerContext));
+    if (m_installerContext.needEncryption) {
+        AddTask(new TaskEncryptResource(m_installerContext));
+    }
+
+    AddTask(new TaskManifestFile(m_installerContext));
+    if (m_installerContext.widgetConfig.packagingType ==
+        PKG_TYPE_HYBRID_WEB_APP)
+    {
+        AddTask(new TaskInstallOspsvc(m_installerContext));
+    }
+
+    AddTask(new TaskDatabase(m_installerContext));
+    AddTask(new TaskAceCheck(m_installerContext));
+    //TODO: remove widgetHandle from this task and move before database task
+    // by now widget handle is needed in ace check
+    // Any error in acecheck while update will break widget
+    AddTask(new TaskSmack(m_installerContext));
+    AddTask(new TaskRemoveBackupFiles(m_installerContext));
+    AddTask(new TaskPkgInfoUpdate(m_installerContext));
+}
+
+void JobWidgetInstall::SendProgress()
+{
+    using namespace PackageManager;
+    if (GetProgressFlag() != false) {
+        if (GetInstallerStruct().progressCallback != NULL) {
+            // send progress signal of pkgmgr
+            GetInstallerStruct().pkgmgrInterface->sendProgress(GetProgressPercent());
+
+            _D("Call widget install progressCallback");
+            GetInstallerStruct().progressCallback(
+                GetInstallerStruct().userParam,
+                GetProgressPercent(),
+                GetProgressDescription());
+        }
+    }
+}
+
+void JobWidgetInstall::SendProgressIconPath(const std::string &path)
+{
+    using namespace PackageManager;
+    if (GetProgressFlag() != false) {
+        if (GetInstallerStruct().progressCallback != NULL) {
+            // send progress signal of pkgmgr
+            GetInstallerStruct().pkgmgrInterface->sendIconPath(path);
+        }
+    }
+}
+
+void JobWidgetInstall::SendFinishedSuccess()
+{
+    using namespace PackageManager;
+    // TODO : sync should move to separate task.
+    sync();
+
+    if (INSTALL_LOCATION_TYPE_PREFER_EXTERNAL == m_installerContext.locationType) {
+        if (m_installerContext.isUpdateMode) {
+            WidgetInstallToExtSingleton::Instance().postUpgrade(true);
+        } else {
+            WidgetInstallToExtSingleton::Instance().postInstallation(true);
+        }
+        WidgetInstallToExtSingleton::Instance().deinitialize();
+    }
+
+    // remove widget install information file
+    unlink(m_installerContext.installInfo.c_str());
+
+    //inform widget info
+    JobWidgetInstall::displayWidgetInfo();
+
+    TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
+
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    _D("Call widget install successfinishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          DPL::ToUTF8String(
+                                              tizenId), Jobs::Exceptions::Success);
+}
+
+void JobWidgetInstall::SendFinishedFailure()
+{
+    using namespace PackageManager;
+    // remove widget install information file
+    unlink(m_installerContext.installInfo.c_str());
+
+    // print error message
+    LOGE(COLOR_ERROR "Error number: %d" COLOR_END, m_exceptionCaught);
+    LOGE(COLOR_ERROR "Message: %s" COLOR_END, m_exceptionMessage.c_str());
+    fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
+
+    TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
+
+    _D("Call widget install failure finishedCallback");
+
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          DPL::ToUTF8String(
+                                              tizenId), m_exceptionCaught);
+}
+
+void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
+{
+    m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
+    m_exceptionMessage = e.GetMessage();
+}
+void JobWidgetInstall::displayWidgetInfo()
+{
+    if (m_installerContext.widgetConfig.webAppType.appType == WrtDB::APP_TYPE_TIZENWEBAPP)
+    {
+        WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
+
+        std::ostringstream out;
+        WidgetLocalizedInfo localizedInfo =
+            W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
+
+        out << std::endl <<
+        "===================================== INSTALLED WIDGET INFO =========" \
+        "============================";
+        out << std::endl << "Name:                        " << localizedInfo.name;
+        out << std::endl << "AppId:                     " << dao.getTzAppId();
+        WidgetSize size = dao.getPreferredSize();
+        out << std::endl << "Width:                       " << size.width;
+        out << std::endl << "Height:                      " << size.height;
+        out << std::endl << "Start File:                  " <<
+        W3CFileLocalization::getStartFile(dao.getTzAppId());
+        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();
+
+        OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
+        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;
+
+        _D("%s", out.str().c_str());
+    }
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/job_widget_install.h b/src_wearable/jobs/widget_install/job_widget_install.h
new file mode 100644 (file)
index 0000000..857863c
--- /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    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 <job.h>
+#include <job_base.h>
+#include <dpl/utils/widget_version.h>
+#include "widget_installer_struct.h"
+#include <widget_install/widget_install_context.h>
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+typedef JobProgressBase<InstallerContext::InstallStep, InstallerContext::INSTALL_END> InstallerBase;
+typedef JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct> WidgetInstallationBase;
+
+class JobWidgetInstall :
+    public Job,
+    public InstallerBase,
+    public WidgetInstallationBase
+
+{
+  private:
+    InstallerContext m_installerContext;
+
+    Jobs::Exceptions::Type m_exceptionCaught;
+    std::string m_exceptionMessage;
+
+  public:
+    /**
+     * @brief Automaticaly sets installation process
+     */
+    JobWidgetInstall(std::string const & widgetPath,
+         std::string const &tzPkgId,
+         const Jobs::WidgetInstall::WidgetInstallationStruct &installerStruct);
+
+    //overrides
+    void SendProgress();
+    void SendFinishedSuccess();
+    void SendFinishedFailure();
+    void SendProgressIconPath(const std::string &path);
+
+    void SaveExceptionData(const Jobs::JobExceptionBase&);
+    void displayWidgetInfo();
+
+    //execution paths
+    void appendNewInstallationTaskList();
+    void appendUpdateInstallationTaskList();
+    void appendRDSUpdateTaskList();
+    void appendRecoveryTaskList();
+    void appendFotaInstallationTaskList();
+    void appendFotaUpdateTaskList();
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_
diff --git a/src_wearable/jobs/widget_install/languages.def b/src_wearable/jobs/widget_install/languages.def
new file mode 100644 (file)
index 0000000..e9439b6
--- /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_wearable/jobs/widget_install/manifest.cpp b/src_wearable/jobs/widget_install/manifest.cpp
new file mode 100755 (executable)
index 0000000..0d509ac
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2012 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    manifest.cpp
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ */
+
+#include "manifest.h"
+#include "libxml_utils.h"
+#include <widget_install/task_manifest_file.h>
+#include <dpl/foreach.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+void writeElement(xmlTextWriterPtr writer, const char * name, DPL::String body)
+{
+    int state = xmlTextWriterWriteElement(writer, BAD_CAST name,
+                                          BAD_CAST DPL::ToUTF8String(
+                                              body).c_str());
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteElement failed");
+    }
+}
+
+void writeText(xmlTextWriterPtr writer, DPL::String text)
+{
+    int state = xmlTextWriterWriteString(writer,
+                                         BAD_CAST DPL::ToUTF8String(text).c_str());
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteText failed");
+    }
+}
+
+void writeElement(xmlTextWriterPtr writer, const char * name, const char * body)
+{
+    int state = xmlTextWriterWriteElement(writer, BAD_CAST name, BAD_CAST body);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteElement failed");
+    }
+}
+
+void writeElementWithOneAttribute(xmlTextWriterPtr writer,
+                                  const char * name,
+                                  DPL::String body,
+                                  const char * nameAttr,
+                                  DPL::String bodyAttr,
+                                  bool condition = true)
+{
+    startElement(writer, name);
+    writeAttribute(writer, nameAttr, bodyAttr, condition);
+    writeText(writer, body);
+    endElement(writer);
+}
+
+void startElement(xmlTextWriterPtr writer, const char * name)
+{
+    int state = xmlTextWriterStartElement(writer, BAD_CAST name);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterStartElement failed");
+    }
+}
+
+void endElement(xmlTextWriterPtr writer)
+{
+    int state = xmlTextWriterEndElement(writer);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterEndElement failed");
+    }
+}
+
+void writeAttribute(xmlTextWriterPtr writer,
+                    const char * name,
+                    DPL::String body,
+                    bool condition = true)
+{
+    if (!condition) {
+        return;
+    }
+    int state = xmlTextWriterWriteAttribute(writer, BAD_CAST name,
+                                            BAD_CAST DPL::ToUTF8String(
+                                                body).c_str());
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error,
+                 "xmlTextWriterWriteAttribute failed");
+    }
+}
+
+void writeAttribute(xmlTextWriterPtr writer,
+                    const char * name,
+                    const char * body,
+                    bool condition = true)
+{
+    if (!condition) {
+        return;
+    }
+    int state = xmlTextWriterWriteAttribute(writer,
+                                            BAD_CAST name,
+                                            BAD_CAST body);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error,
+                 "xmlTextWriterWriteAttribute failed");
+    }
+}
+
+void Manifest::generate(DPL::String filename)
+{
+    xmlTextWriterPtr writer;
+    int state;
+
+    //compression set to 0
+    writer = xmlNewTextWriterFilename(DPL::ToUTF8String(filename).c_str(), 0);
+
+    if (writer == NULL) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlNewTextWriterFilename failed");
+    }
+    state = xmlTextWriterSetIndent(writer, 1);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterSetIndent failed");
+    }
+
+    state = xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterStartDocument failed");
+    }
+    this->serialize(writer);
+    state = xmlTextWriterEndDocument(writer);
+    if (state < 0) {
+        ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterEndDocument failed");
+    }
+    if (writer != NULL) {
+        xmlFreeTextWriter(writer);
+        writer = NULL;
+    }
+}
+
+void Manifest::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "manifest");
+    {
+        writeAttribute(writer, "xmlns", "http://tizen.org/ns/packages");
+        writeAttribute(writer, "package", this->package);
+        writeAttribute(writer, "type", this->type);
+        writeAttribute(writer, "version", this->version);
+        if (!!this->installLocation) {
+            writeAttribute(writer, "install-location", (*this->installLocation));
+        }
+        writeAttribute(writer, "storeclient-id", this->storeClientId,
+                !this->storeClientId.empty());
+        writeAttribute(writer, "csc_path", this->cscPath,
+                !this->cscPath.empty());
+
+        FOREACH(l, this->label)
+        {
+            writeElementWithOneAttribute(writer, "label", l->getString(),
+                                         "xml:lang", l->getLang(), l->hasLang());
+        }
+        FOREACH(i, this->icon)
+        {
+            writeElementWithOneAttribute(writer, "icon", i->getString(),
+                                         "xml:lang", i->getLang(), i->hasLang());
+        }
+        FOREACH(a, this->author)
+        {
+            a->serialize(writer);
+        }
+        FOREACH(d, this->description)
+        {
+            writeElementWithOneAttribute(writer, "description", d->getString(),
+                                         "xml:lang", d->getLang(), d->hasLang());
+        }
+        //FOREACH(c, this->compatibility) { c->serialize(writer); }
+        //FOREACH(d, this->deviceProfile) { d->serialize(writer); }
+#ifdef SERVICE_ENABLED
+        FOREACH(s, this->serviceApplication) {
+            s->serialize(writer);
+        }
+#endif
+        FOREACH(u, this->uiApplication) {
+            u->serialize(writer);
+        }
+#ifdef IME_ENABLED
+        FOREACH(i, this->imeApplication) {
+            i->serialize(writer);
+        }
+#endif
+        //FOREACH(f, this->font) { f->serialize(writer); }
+#ifdef DBOX_ENABLED
+        FOREACH(l, this->livebox) {
+            l->serialize(writer);
+        }
+#endif
+        FOREACH(acc, this->account)
+        {
+            acc->serialize(writer);
+        }
+
+        if (!this->privileges.isEmpty()) {
+            this->privileges.serialize(writer);
+        }
+    }
+    endElement(writer);
+}
+
+void Author::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "author");
+    writeAttribute(writer, "email", this->email, !this->email.empty());
+    writeAttribute(writer, "href", this->href, !this->href.empty());
+    writeAttribute(writer, "xml:lang", this->lang, !this->lang.empty());
+    writeText(writer, body);
+    endElement(writer);
+}
+
+void UiApplication::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "ui-application");
+    writeAttribute(writer, "appid", this->appid);
+    writeAttribute(writer, "exec", this->exec);
+    if (!!this->multiple) {
+        writeAttribute(writer, "multiple", (*this->multiple) ? "true" : "false");
+    }
+    if (!!this->nodisplay) {
+        writeAttribute(writer,
+                       "nodisplay",
+                       (*this->nodisplay) ? "true" : "false");
+    }
+    if (!!this->taskmanage) {
+        writeAttribute(writer,
+                       "taskmanage",
+                       (*this->taskmanage) ? "true" : "false");
+    }
+    writeAttribute(writer, "type", this->type);
+    writeAttribute(writer, "extraid", this->extraid);
+    if (!!this->categories) {
+        writeAttribute(writer, "categories", (*this->categories));
+    }
+    FOREACH(l, this->label)
+    {
+        writeElementWithOneAttribute(writer, "label",
+                                     l->getString(), "xml:lang",
+                                     l->getLang(), l->hasLang());
+    }
+    FOREACH(i, this->icon)
+    {
+        startElement(writer, "icon");
+        {
+            writeAttribute(writer, "xml:lang", i->getLang(), i->hasLang());
+            writeAttribute(writer, "section", "small", i->isSmall());
+            writeText(writer, i->getString());
+        }
+        endElement(writer);
+    }
+    FOREACH(a, this->appControl)
+    {
+        a->serialize(writer);
+    }
+    FOREACH(c, this->appCategory)
+    {
+        startElement(writer, "category");
+        writeAttribute(writer, "name", *c);
+        endElement(writer);
+    }
+    FOREACH(m, this->metadata) {
+        m->serialize(writer);
+    }
+    endElement(writer);
+}
+
+#ifdef IME_ENABLED
+void ImeApplication::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "ime");
+    writeAttribute(writer, "appid", this->appid);
+    {
+        startElement(writer, "uuid");
+        writeText(writer, this->uuid);
+        endElement(writer);
+        FOREACH(l, this->label)
+        {
+            writeElementWithOneAttribute(writer, "label", l->getString(), "xml:lang", l->getLang(), l->hasLang());
+        }
+        startElement(writer, "languages");
+        {
+            FOREACH(g, this->language)
+            {
+                startElement(writer, "language");
+                writeText(writer, *g);
+                endElement(writer);
+            }
+        }
+        endElement(writer);
+        startElement(writer, "type");
+        writeText(writer, this->iseType);
+        endElement(writer);
+        startElement(writer, "options");
+        {
+            FOREACH(o, this->option)
+            {
+                startElement(writer, "option");
+                writeText(writer, *o);
+                endElement(writer);
+            }
+        }
+        endElement(writer);
+    }
+    endElement(writer);
+}
+#endif
+
+#ifdef SERVICE_ENABLED
+void ServiceApplication::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "ui-application");
+    writeAttribute(writer, "component-type", this->component);
+    writeAttribute(writer, "auto-restart", (!!this->autoRestart && (*this->autoRestart)) ? "true" : "false");
+    writeAttribute(writer, "on-boot", (!!this->onBoot && (*this->onBoot)) ? "true" : "false");
+    writeAttribute(writer, "appid", this->appid);
+    writeAttribute(writer, "exec", this->exec);
+    writeAttribute(writer, "extraid", this->extraid);
+    if (!!this->nodisplay) {
+        writeAttribute(writer, "nodisplay", (*this->nodisplay) ? "true" : "false");
+    }
+    if (!!this->multiple) {
+        writeAttribute(writer, "multiple", (*this->multiple) ? "true" : "false");
+    }
+    writeAttribute(writer, "type", this->type);
+    if (!!this->taskmanage) {
+        writeAttribute(writer, "taskmanage", (*this->taskmanage) ? "true" : "false");
+    }
+    if (!!this->categories) {
+        writeAttribute(writer, "categories", (*this->categories));
+    }
+    FOREACH(l, this->label)
+    {
+        writeElementWithOneAttribute(writer, "label",
+                                     l->getString(), "xml:lang",
+                                     l->getLang(), l->hasLang());
+    }
+    FOREACH(i, this->icon)
+    {
+        writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang",
+                                     i->getLang(), i->hasLang());
+    }
+    FOREACH(a, this->appControl)
+    {
+        a->serialize(writer);
+    }
+    FOREACH(c, this->appCategory)
+    {
+        startElement(writer, "category");
+        writeAttribute(writer, "name", *c);
+    endElement(writer);
+}
+    FOREACH(m, this->metadata) {
+        m->serialize(writer);
+    }
+    endElement(writer);
+}
+#endif
+
+void AppControl::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "app-control");
+    FOREACH(o, this->operation)
+    {
+        startElement(writer, "operation");
+        writeAttribute(writer, "name", *o);
+        endElement(writer);
+    }
+    FOREACH(u, this->uri)
+    {
+        startElement(writer, "uri");
+        writeAttribute(writer, "name", *u);
+        endElement(writer);
+    }
+    FOREACH(m, this->mime)
+    {
+        startElement(writer, "mime");
+        writeAttribute(writer, "name", *m);
+        endElement(writer);
+    }
+    endElement(writer);
+}
+
+#ifdef DBOX_ENABLED
+void LiveBox::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "livebox");
+    if (!this->liveboxId.empty()) {
+        writeAttribute(writer, "appid", this->liveboxId);
+    }
+
+    if (!this->primary.empty()) {
+        writeAttribute(writer, "primary", this->primary);
+    }
+
+    if (!this->updatePeriod.empty()) {
+        writeAttribute(writer, "period", this->updatePeriod);
+    }
+
+    writeAttribute(writer, "abi", "html");
+    writeAttribute(writer, "network", "true");
+    writeAttribute(writer, "nodisplay", "false");
+
+    if (!this->label.empty()) {
+        int defaultLabelChk = 0;
+        FOREACH(m, this->label)
+        {
+            std::pair<DPL::String, DPL::String> boxLabel = *m;
+            startElement(writer, "label");
+            if (!boxLabel.first.empty()) {
+                writeAttribute(writer, "xml:lang", boxLabel.first);
+            } else {
+                defaultLabelChk++;
+            }
+            writeText(writer, boxLabel.second);
+            endElement(writer);
+        }
+        if(!defaultLabelChk) {
+            startElement(writer, "label");
+            writeText(writer, DPL::FromUTF8String("NO NAME"));
+            endElement(writer);
+        }
+    }
+    if (!this->icon.empty()) {
+        startElement(writer, "icon");
+        writeText(writer, this->icon);
+        endElement(writer);
+    }
+
+    if (!this->autoLaunch.empty()) {
+        startElement(writer, "launch");
+        writeText(writer, this->autoLaunch);
+        endElement(writer);
+    }
+
+    if (!this->box.boxSrc.empty() &&
+        !this->box.boxMouseEvent.empty() &&
+        !this->box.boxSize.empty())
+    {
+        startElement(writer, "box");
+        writeAttribute(writer, "type", "buffer");
+        writeAttribute(writer, "mouse_event", this->box.boxMouseEvent);
+        writeAttribute(writer, "touch_effect", this->box.boxTouchEffect);
+
+        FOREACH(it, this->box.boxSize)
+        {
+            startElement(writer, "size");
+            if (!(*it).m_preview.empty()) {
+                writeAttribute(writer, "preview", (*it).m_preview);
+            }
+            if (!(*it).m_useDecoration.empty()) {
+                writeAttribute(writer, "need_frame", (*it).m_useDecoration);
+            } else {
+                // default value of use-decoration is "true"
+                writeAttribute(writer, "need_frame", DPL::String(L"true"));
+            }
+
+            writeText(writer, (*it).m_size);
+            endElement(writer);
+        }
+
+        startElement(writer, "script");
+        writeAttribute(writer, "src", this->box.boxSrc);
+        endElement(writer);
+
+        endElement(writer);
+
+        if (!this->box.pdSrc.empty() &&
+            !this->box.pdWidth.empty() &&
+            !this->box.pdHeight.empty())
+        {
+            startElement(writer, "pd");
+            writeAttribute(writer, "type", "buffer");
+
+            startElement(writer, "size");
+            DPL::String pdSize = this->box.pdWidth + DPL::String(L"x") +
+                this->box.pdHeight;
+            writeText(writer, pdSize);
+            endElement(writer);
+
+            startElement(writer, "script");
+            writeAttribute(writer, "src", this->box.pdSrc);
+            endElement(writer);
+
+            endElement(writer);
+        }
+    }
+
+    endElement(writer);
+}
+#endif
+
+void Account::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "account");
+    {
+        startElement(writer, "account-provider");
+        writeAttribute(writer, "appid", this->provider.appid);
+        writeAttribute(writer, "multiple-accounts-support",
+                this->provider.multiAccount);
+
+        FOREACH(i, this->provider.icon)
+        {
+            startElement(writer, "icon");
+            writeAttribute(writer, "section", i->first);
+            writeText(writer, i->second);
+            endElement(writer);
+        }
+
+        bool setDefaultLang = false;
+        FOREACH(n, this->provider.name)
+        {
+            if (!setDefaultLang && n->getLang() == L"en-gb") {
+                writeElement(writer, "label", n->getString());
+                setDefaultLang = true;
+            }
+            writeElementWithOneAttribute(writer, "label",
+                    n->getString(), "xml:lang",
+                    n->getLang(), n->hasLang());
+        }
+        if (!setDefaultLang) {
+            writeElement(writer, "label", this->provider.name.begin()->getString());
+        }
+
+        FOREACH(c, this->provider.capability)
+        {
+            startElement(writer, "capability");
+            writeText(writer, *c);
+            endElement(writer);
+        }
+        endElement(writer);
+    }
+    endElement(writer);
+}
+
+void Privilege::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "privileges");
+    {
+        FOREACH(it, this->name)
+        {
+            startElement(writer, "privilege");
+            writeText(writer, *it);
+            endElement(writer);
+        }
+    }
+    endElement(writer);
+}
+
+void Metadata::serialize(xmlTextWriterPtr writer)
+{
+    startElement(writer, "metadata");
+    writeAttribute(writer, "key", *this->key);
+    if (!!this->value) {
+        writeAttribute(writer, "value", *this->value);
+    }
+    endElement(writer);
+}
+} //namespace Jobs
+} //namespace WidgetInstall
diff --git a/src_wearable/jobs/widget_install/manifest.h b/src_wearable/jobs/widget_install/manifest.h
new file mode 100755 (executable)
index 0000000..7d132fc
--- /dev/null
@@ -0,0 +1,688 @@
+/*
+ * Copyright (c) 2012 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    manifest.h
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ */
+
+#ifndef INSTALLER_JOBS_MANIFEST_H
+#define INSTALLER_JOBS_MANIFEST_H
+
+#include <list>
+
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+#include <dpl/string.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+/**
+ * @brief string with optional language attribute
+ */
+class StringWithLang
+{
+  public:
+    StringWithLang() { }
+    StringWithLang(DPL::String s) : string(s) { }
+    StringWithLang(DPL::String s, DPL::String l) : string(s), lang(l) { }
+    DPL::String getString()
+    {
+        return this->string;
+    }
+    DPL::String getLang()
+    {
+        return this->lang;
+    }
+    bool hasLang()
+    {
+        return !this->lang.empty();
+    }
+    int operator==(const StringWithLang &other)
+    {
+        return (DPL::ToUTF8String(other.string) == DPL::ToUTF8String(string)) &&
+               (DPL::ToUTF8String(other.lang) == DPL::ToUTF8String(lang));
+    }
+
+  private:
+    DPL::String string;
+    DPL::String lang;
+};
+
+class IconType : public StringWithLang
+{
+    public:
+      IconType() { }
+      IconType(DPL::String s) : StringWithLang(s), small(false) { }
+      IconType(DPL::String s, DPL::String l) : StringWithLang(s, l), small(false) { }
+      IconType(DPL::String s, bool m) : StringWithLang(s), small(m) { }
+      IconType(DPL::String s, DPL::String l, bool m) : StringWithLang(s, l), small(m) { }
+
+      bool isSmall()
+      {
+          return small;
+      }
+
+      int operator==(const IconType &other)
+      {
+          return (StringWithLang::operator==(other) && (other.small == small));
+      }
+
+    private:
+        bool small;
+};
+
+typedef StringWithLang LabelType, DescriptionType;
+
+/**
+ * These types are basicaly strings but they should allow usage of different
+ * range of characters or words (details in XML spec.).
+ * For simplicity DPL::Strings are used, although this can lead to XML
+ * validation
+ * errors (related to usage of not allowed characters in given places).
+ */
+typedef DPL::String NcnameType, NmtokenType, AnySimpleType, LangType;
+typedef DPL::String OperationType, MimeType, UriType, TypeType, PackageType;
+typedef DPL::OptionalString InstallLocationType, CategoriesType;
+typedef DPL::String AppCategoryType;
+typedef DPL::OptionalString KeyType, ValueType;
+
+#ifdef IME_ENABLED
+typedef DPL::String UuidType, LanguageType, IseTypeType, OptionType;
+#endif
+
+#ifdef SERVICE_ENABLED
+typedef DPL::String ComponentType;
+#endif
+
+/**
+ * xmllib2 wrappers
+ */
+void writeElement(xmlTextWriterPtr writer, const char * name, DPL::String body);
+void writeText(xmlTextWriterPtr writer, DPL::String text);
+void writeElement(xmlTextWriterPtr writer, const char * name, const char * body);
+void writeElementWithOneAttribute(xmlTextWriterPtr writer,
+                                  const char * name,
+                                  const char * body,
+                                  const char * nameAttr,
+                                  DPL::String bodyAttr,
+                                  bool condition = true);
+void startElement(xmlTextWriterPtr writer, const char * name);
+void endElement(xmlTextWriterPtr writer);
+void writeAttribute(xmlTextWriterPtr writer, const char * name,
+                    DPL::String body, bool condition);
+void writeAttribute(xmlTextWriterPtr writer, const char * name,
+                    const char * body, bool condition);
+
+/**
+ * @brief author element
+ */
+class Author
+{
+  public:
+    Author() {}
+    Author(AnySimpleType e,
+           NcnameType h,
+           LangType l,
+           DPL::String b) :
+        email(e), href(h), lang(l), body(b) {}
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    AnySimpleType email;
+    NcnameType href;
+    LangType lang;
+    DPL::String body;
+};
+
+typedef Author AuthorType;
+
+/**
+ * @brief application-service element
+ */
+class AppControl
+{
+  public:
+    AppControl() {}
+    void addOperation(const OperationType &x)
+    {
+        this->operation.push_back(x);
+    }
+    void addUri(const UriType &x)
+    {
+        this->uri.push_back(x);
+    }
+    void addMime(const MimeType &x)
+    {
+        this->mime.push_back(x);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    std::list<OperationType> operation; //attr name AnySimpleType
+    std::list<UriType> uri; //attr name AnySimpleType
+    std::list<MimeType> mime; //attr name AnySimpleType
+};
+
+typedef AppControl AppControlType;
+
+/**
+ * @brief account element
+ */
+typedef std::list<std::pair<DPL::String, DPL::String>> IconListType;
+typedef std::list<LabelType> DisplayNameListType;
+typedef std::list<DPL::String> AccountCapabilityType;
+
+struct AccountProvider
+{
+    NcnameType appid;
+    NcnameType multiAccount;
+    IconListType icon;
+    DisplayNameListType name;
+    AccountCapabilityType capability;
+};
+
+typedef AccountProvider AccountProviderType;
+
+class Account
+{
+  public:
+    Account() {}
+    void addAccountProvider(const AccountProvider &x)
+    {
+        this->provider = x;
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    AccountProviderType provider;
+};
+
+class Privilege
+{
+  public:
+    Privilege() {}
+    void addPrivilegeName(const DPL::String &x)
+    {
+        this->name.push_back(x);
+    }
+    bool isEmpty()
+    {
+        return this->name.empty();
+    }
+
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    std::list<DPL::String> name;
+};
+
+typedef Privilege PrivilegeType;
+
+class Metadata
+{
+  public:
+    Metadata(KeyType k, ValueType v) :
+        key(k),
+        value(v)
+    {}
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    KeyType key;
+    ValueType value;
+};
+
+typedef Metadata MetadataType;
+
+#ifdef IME_ENABLED
+/**
+ * @brief ime-application element
+ */
+class ImeApplication
+{
+  public:
+    ImeApplication() {}
+    void setAppid(const NcnameType &x)
+    {
+        this->appid = x;
+    }
+    void addLabel(const LabelType &x)
+    {
+        this->label.push_back(x);
+    }
+    void addUuid(const UuidType &x)
+    {
+        this->uuid = x;
+    }
+    void addLanguage(const LanguageType &x)
+    {
+        this->language.push_back(x);
+    }
+    void addIseType(const IseTypeType &x)
+    {
+        this->iseType = x;
+    }
+    void addOption(const OptionType &x)
+    {
+        this->option.push_back(x);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    NcnameType appid;
+    std::list<LabelType> label;
+    DPL::String uuid;
+    std::list<LanguageType> language;
+    DPL::String iseType;
+    std::list<OptionType> option;
+};
+
+typedef ImeApplication ImeApplicationType;
+#endif
+
+#ifdef SERVICE_ENABLED
+/**
+ * @brief service-application element
+ */
+
+class ServiceApplication
+{
+  public:
+    ServiceApplication() {}
+    void setAppid(const NcnameType &x)
+    {
+        this->appid = x;
+    }
+    void setComponent(const ComponentType &x)
+    {
+        this->component = x;
+    }
+    void setAutoRestart(bool x)
+    {
+        this->autoRestart = x;
+    }
+    void setOnBoot(bool x)
+    {
+        this->onBoot = x;
+    }
+    void setExec(const AnySimpleType &x)
+    {
+        this->exec = x;
+    }
+    void setExtraid(const NcnameType &x)
+    {
+        this->extraid = x;
+    }
+    void setNodisplay(bool x)
+    {
+        this->nodisplay = x;
+    }
+    void setMultiple(bool x)
+    {
+        this->multiple = x;
+    }
+    void setType(const TypeType &x)
+    {
+        this->type = x;
+    }
+    void setTaskmanage(bool x)
+    {
+        this->taskmanage = x;
+    }
+    void setCategories(const NcnameType &x)
+    {
+        this->categories = x;
+    }
+    void addLabel(const LabelType &x)
+    {
+        this->label.push_back(x);
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void addAppControl(const AppControlType &x)
+    {
+        this->appControl.push_back(x);
+    }
+    void addAppCategory(const AppCategoryType &x)
+    {
+        this->appCategory.push_back(x);
+    }
+    void addMetadata(const MetadataType &m)
+    {
+        this->metadata.push_back(m);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+    DPL::OptionalBool isNoDisplay() {
+        return this->nodisplay;
+    }
+
+  private:
+    NcnameType appid;
+    DPL::String component;
+    DPL::OptionalBool autoRestart;
+    DPL::OptionalBool onBoot;
+    AnySimpleType exec;
+    NcnameType extraid;
+    DPL::OptionalBool nodisplay;
+    DPL::OptionalBool multiple;
+    TypeType type;
+    DPL::OptionalBool taskmanage;
+    CategoriesType categories;
+    std::list<LabelType> label;
+    std::list<IconType> icon;
+    std::list<AppControlType> appControl;
+    std::list<AppCategoryType> appCategory;
+    std::list<MetadataType> metadata;
+};
+
+typedef ServiceApplication ServiceApplicationType;
+
+#endif
+
+/**
+ * @brief ui-application element
+ */
+class UiApplication
+{
+  public:
+    UiApplication() {}
+    void setAppid(const NcnameType &x)
+    {
+        this->appid = x;
+    }
+    void setExtraid(const NcnameType &x)
+    {
+        this->extraid = x;
+    }
+    void setExec(const AnySimpleType &x)
+    {
+        this->exec = x;
+    }
+    void setMultiple(bool x)
+    {
+        this->multiple = x;
+    }
+    void setNodisplay(bool x)
+    {
+        this->nodisplay = x;
+    }
+    void setTaskmanage(bool x)
+    {
+        this->taskmanage = x;
+    }
+    void setType(const TypeType &x)
+    {
+        this->type = x;
+    }
+    void setCategories(const NcnameType &x)
+    {
+        this->categories = x;
+    }
+    void addLabel(const LabelType &x)
+    {
+        this->label.push_back(x);
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void addAppControl(const AppControlType &x)
+    {
+        this->appControl.push_back(x);
+    }
+    void addAppCategory(const AppCategoryType &x)
+    {
+        this->appCategory.push_back(x);
+    }
+    void addMetadata(const MetadataType &m)
+    {
+        this->metadata.push_back(m);
+    }
+    void serialize(xmlTextWriterPtr writer);
+
+    DPL::OptionalBool isNoDisplay() {
+        return this->nodisplay;
+    }
+
+  private:
+    NcnameType appid;
+    NcnameType extraid;
+    AnySimpleType exec;
+    DPL::OptionalBool multiple;
+    DPL::OptionalBool nodisplay;
+    DPL::OptionalBool taskmanage;
+    TypeType type;
+    CategoriesType categories;
+    std::list<LabelType> label;
+    std::list<IconType> icon;
+    std::list<AppControlType> appControl;
+    std::list<AppCategoryType> appCategory;
+    std::list<MetadataType> metadata;
+};
+
+typedef UiApplication UiApplicationType;
+
+#ifdef DBOX_ENABLED
+/**
+ * @brief LiveBox element
+ */
+typedef WrtDB::ConfigParserData::LiveboxInfo::BoxSizeList BoxSizeType;
+typedef WrtDB::ConfigParserData::LiveboxInfo::BoxLabelList BoxLabelType;
+
+struct BoxInfo
+{
+    NcnameType boxSrc;
+    NcnameType boxMouseEvent;
+    NcnameType boxTouchEffect;
+    BoxSizeType boxSize;
+    NcnameType pdSrc;
+    NcnameType pdWidth;
+    NcnameType pdHeight;
+};
+typedef BoxInfo BoxInfoType;
+
+class LiveBox
+{
+  public:
+    LiveBox() { }
+    void setLiveboxId(const NcnameType &x)
+    {
+        this->liveboxId = x;
+    }
+    void setPrimary(const NcnameType &x)
+    {
+        this->primary = x;
+    }
+    void setAutoLaunch(const NcnameType &x)
+    {
+        this->autoLaunch = x;
+    }
+    void setUpdatePeriod(const NcnameType &x)
+    {
+        this->updatePeriod = x;
+    }
+    void setLabel(const BoxLabelType &x)
+    {
+        this->label = x;
+    }
+    void setIcon(const NcnameType &x)
+    {
+        this->icon = x;
+    }
+    void setBox(const BoxInfoType &x)
+    {
+        this->box = x;
+    }
+
+    void serialize(xmlTextWriterPtr writer);
+
+  private:
+    NcnameType liveboxId;
+    NcnameType primary;
+    NcnameType autoLaunch;
+    NcnameType updatePeriod;
+    NcnameType timeout;
+    BoxLabelType label;
+    NcnameType icon;
+    NcnameType lang;
+    BoxInfoType box;
+};
+
+typedef LiveBox LiveBoxInfo;
+#endif
+
+/**
+ * @brief manifest element
+ *
+ * Manifest xml file representation.
+ */
+class Manifest
+{
+  public:
+    Manifest() {}
+    void serialize(xmlTextWriterPtr writer);
+    void generate(DPL::String filename);
+
+    void addLabel(const LabelType &x)
+    {
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+        auto pos = std::find(label.begin(), label.end(), x);
+        if (pos == label.end()) {
+            this->label.push_back(x);
+        }
+#else
+        this->label.push_back(x);
+#endif
+    }
+    void addIcon(const IconType &x)
+    {
+        this->icon.push_back(x);
+    }
+    void addAuthor(const AuthorType &x)
+    {
+        this->author.push_back(x);
+    }
+    void addDescription(const DescriptionType &x)
+    {
+        this->description.push_back(x);
+    }
+    //    void addCompatibility(const CompatibilityType &x)
+    //    {
+    //        this->compatibility.push_back(x);
+    //    }
+    //    void addDeviceProfile(const DeviceProfileType &x)
+    //    {
+    //        this->deviceProfile.push_back(x);
+    //    }
+    void addUiApplication(const UiApplicationType &x)
+    {
+        this->uiApplication.push_back(x);
+    }
+#ifdef IME_ENABLED
+    void addImeApplication(const ImeApplicationType &x)
+    {
+        this->imeApplication.push_back(x);
+    }
+#endif
+#ifdef SERVICE_ENABLED
+    void addServiceApplication(const ServiceApplicationType &x)
+    {
+        this->serviceApplication.push_back(x);
+    }
+#endif
+    //    void addFont(const FontType &x) { this->font.push_back(x); }
+
+#ifdef DBOX_ENABLED
+    void addLivebox(const LiveBoxInfo &x)
+    {
+        this->livebox.push_back(x);
+    }
+#endif
+
+    void addAccount(const Account &x)
+    {
+        this->account.push_back(x);
+    }
+
+    void addPrivileges(const PrivilegeType &x)
+    {
+        this->privileges = x;
+    }
+
+    void setInstallLocation(const InstallLocationType &x)
+    {
+        this->installLocation = x;
+    }
+    void setPackage(const NcnameType &x)
+    {
+        this->package = x;
+    }
+    void setType(const PackageType &x)
+    {
+        this->type = x;
+    }
+    void setVersion(const NmtokenType &x)
+    {
+        this->version = x;
+    }
+    void setStoreClientId(const NcnameType &x)
+    {
+        this->storeClientId= x;
+    }
+    void setCscPath(const NcnameType &x)
+    {
+        this->cscPath = x;
+    }
+
+  private:
+    std::list<LabelType> label;
+    std::list<IconType> icon;
+    std::list<AuthorType> author;
+    std::list<DescriptionType> description;
+    //    std::list<CompatibilityType> compatibility;
+    //    std::list<DeviceProfileType> deviceProfile;
+#ifdef SERVICE_ENABLED
+    std::list<ServiceApplicationType> serviceApplication;
+#endif
+    std::list<UiApplicationType> uiApplication;
+#ifdef IME_ENABLED
+    std::list<ImeApplicationType> imeApplication;
+#endif
+    //    std::list<FontType> font;
+#ifdef DBOX_ENABLED
+    std::list<LiveBoxInfo> livebox;
+#endif
+    InstallLocationType installLocation;
+    NcnameType package;
+    PackageType type;
+    NmtokenType version;
+    std::list<Account> account;
+    PrivilegeType privileges;
+    NcnameType storeClientId;
+    NcnameType cscPath;
+
+};
+} //namespace Jobs
+} //namespace WidgetInstall
+
+#endif //INSTALLER_JOBS_MANIFEST_H
diff --git a/src_wearable/jobs/widget_install/task_ace_check.cpp b/src_wearable/jobs/widget_install/task_ace_check.cpp
new file mode 100755 (executable)
index 0000000..7285492
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * 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 <utility>
+#include <vector>
+#include <string>
+
+#include <widget_install/task_ace_check.h>
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/job_widget_install.h>
+
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <ace_api_install.h>
+
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskAceCheck::TaskAceCheck(InstallerContext& context) :
+    DPL::TaskDecl<TaskAceCheck>(this),
+    m_context(context)
+{
+    AddStep(&TaskAceCheck::StartStep);
+    AddStep(&TaskAceCheck::StepPrepareForAce);
+    AddStep(&TaskAceCheck::StepAceCheck);
+    AddStep(&TaskAceCheck::StepProcessAceResponse);
+    AddStep(&TaskAceCheck::StepCheckAceResponse);
+    AddStep(&TaskAceCheck::EndStep);
+}
+
+void TaskAceCheck::StepPrepareForAce()
+{
+    m_context.featureLogic =
+        FeatureLogicPtr(new FeatureLogic(m_context.widgetConfig.tzAppid));
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_ACE_PREPARE,
+        "Widget Access Control Check Prepared");
+}
+
+void TaskAceCheck::StepAceCheck()
+{
+    WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
+    _D("StepAceCheck!");
+    // This widget does not use any device cap
+    if (m_context.featureLogic->isDone()) {
+        return;
+    }
+
+    _D("StepAceCheck!");
+    DPL::String deviceCap = m_context.featureLogic->getDevice();
+
+    _D("StepAceCheck!");
+    _D("DevCap is : %ls", deviceCap.c_str());
+
+    std::string devCapStr = DPL::ToUTF8String(deviceCap);
+    ace_policy_result_t policyResult = ACE_DENY;
+
+    if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
+        _D("This widget is preloaded. So ace check will be skiped");
+        policyResult = ACE_PERMIT;
+    } else {
+        ace_return_t ret = ace_get_policy_result(
+                const_cast<const ace_resource_t>(devCapStr.c_str()),
+                dao.getHandle(),
+                &policyResult);
+        if (ACE_OK != ret) {
+            ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
+                    "ACE check failure");
+        }
+    }
+
+    _D("PolicyResult is : %d", static_cast<int>(policyResult));
+    m_context.staticPermittedDevCaps.insert(std::make_pair(deviceCap,
+                                                           policyResult ==
+                                                           ACE_PERMIT));
+
+    m_context.featureLogic->setAceResponse(policyResult != ACE_DENY);
+}
+
+void TaskAceCheck::StepProcessAceResponse()
+{
+    if (m_context.widgetConfig.packagingType ==
+        WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+    {
+        return;
+    }
+
+    _D("StepProcessAceResponse");
+    m_context.featureLogic->next();
+
+    // No device caps left to process
+    if (m_context.featureLogic->isDone()) {
+        WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
+#ifdef SERVICE_ENABLED
+        std::list<WrtDB::DbWidgetHandle> serviceList;
+        FOREACH(it , m_context.widgetConfig.configInfo.serviceAppInfoList){
+             WrtDB::WidgetDAO serviceDao(it->serviceId);
+             serviceList.push_back(serviceDao.getHandle());
+        }
+#endif
+        _D("All responses has been received from ACE.");
+        // Data to convert to C API
+        std::vector<std::string> devCaps;
+        std::vector<bool> devCapsSmack;
+        // Saving static dev cap permissions
+        FOREACH(cap, m_context.staticPermittedDevCaps) {
+            _D("staticPermittedDevCaps : %ls smack: %d", cap->first.c_str(), cap->second);
+            std::string devCapStr = DPL::ToUTF8String(cap->first);
+            devCaps.push_back(devCapStr);
+            devCapsSmack.push_back(cap->second);
+        }
+        ace_requested_dev_cap_list_t list;
+        list.count = devCaps.size();
+        list.items = new ace_requested_dev_cap_t[list.count];
+
+        for (unsigned int i = 0; i < devCaps.size(); ++i) {
+            list.items[i].device_capability =
+                const_cast<const ace_resource_t>(devCaps[i].c_str());
+            list.items[i].smack_granted =
+                devCapsSmack[i] ? ACE_TRUE : ACE_FALSE;
+        }
+        //TODO: remove dao.getHandle()
+        int ret = ace_set_requested_dev_caps(dao.getHandle(), &list);
+#ifdef SERVICE_ENABLED
+        FOREACH(it, serviceList){
+            ret |= ace_set_requested_dev_caps(*it, &list);
+        }
+#endif
+        delete[] list.items;
+
+        if (ACE_OK != static_cast<ace_return_t>(ret)) {
+            ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
+                                             "ACE failure");
+        }
+
+        std::set<std::string> acceptedFeature;
+        auto it = m_context.featureLogic->resultBegin();
+        for (; it != m_context.featureLogic->resultEnd(); ++it) {
+            if (!(it->rejected)) {
+                acceptedFeature.insert(DPL::ToUTF8String(it->name));
+            }
+        }
+        ace_feature_list_t featureList;
+        featureList.count = acceptedFeature.size();
+        featureList.items = new ace_string_t[featureList.count];
+
+        size_t i = 0;
+        for (std::set<std::string>::const_iterator iter = acceptedFeature.begin();
+             iter != acceptedFeature.end(); ++iter)
+        {
+            _D("Accepted feature item: %s", iter->c_str());
+            featureList.items[i] = const_cast<char *>(iter->c_str());
+            i++;
+        }
+
+        //TODO: remove dao.getHandle()
+        ret = ace_set_accepted_feature(dao.getHandle(), &featureList);
+#ifdef SERVICE_ENABLED
+        FOREACH(it, serviceList){
+            ret |= ace_set_accepted_feature(*it, &featureList);
+        }
+#endif
+        delete[] featureList.items;
+
+        if (ACE_OK != static_cast<ace_return_t>(ret)) {
+            _E("Error in ace_set_feature");
+            ThrowMsg(Exceptions::AceCheckFailed, "Instalation failure. "
+                                             "ace_set_feature failure.");
+        }
+        return;
+    }
+
+    _D("Next device cap.");
+    // Process next device cap
+    SwitchToStep(&TaskAceCheck::StepAceCheck);
+}
+
+void TaskAceCheck::StepCheckAceResponse()
+{
+    _D("Checking ACE response");
+    if (m_context.featureLogic->isRejected()) {
+        _E("Installation failure. Some devCap was not accepted by ACE.");
+        ThrowMsg(
+            Exceptions::PrivilegeLevelViolation,
+            "Instalation failure. "
+            "Some deviceCap was not accepted by ACE.");
+    }
+    _D("Updating \"feature reject status\" in database!");
+    auto it = m_context.featureLogic->resultBegin();
+    auto end = m_context.featureLogic->resultEnd();
+    for (; it != end; ++it) {
+        _D("  |-  Feature: %ls has reject status: %d", it->name.c_str(), it->rejected);
+        if (it->rejected) {
+            WrtDB::WidgetDAO dao(m_context.widgetConfig.tzAppid);
+            dao.updateFeatureRejectStatus(*it);
+
+#ifdef SERVICE_ENABLED
+            FOREACH( svcApp , m_context.widgetConfig.configInfo.serviceAppInfoList){
+                WrtDB::WidgetDAO dao(svcApp->serviceId);
+                dao.updateFeatureRejectStatus(*it);
+            }
+#endif
+        }
+    }
+    _D("Installation continues...");
+}
+
+void TaskAceCheck::StartStep()
+{
+    LOGD("--------- <TaskAceCheck> : START ----------");
+}
+
+void TaskAceCheck::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_ACE_CHECK,
+        "Widget Access Control Check Finished");
+
+    LOGD("--------- <TaskAceCheck> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_ace_check.h b/src_wearable/jobs/widget_install/task_ace_check.h
new file mode 100644 (file)
index 0000000..e4ce90d
--- /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    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>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskAceCheck :
+    public DPL::TaskDecl<TaskAceCheck>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StepPrepareForAce();
+    void StepAceCheck();
+    void StepProcessAceResponse();
+    void StepCheckAceResponse();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskAceCheck(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_ACE_CHECK_H */
diff --git a/src_wearable/jobs/widget_install/task_certify.cpp b/src_wearable/jobs/widget_install/task_certify.cpp
new file mode 100644 (file)
index 0000000..3e8925c
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * 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 <sstream>
+#include <unistd.h>
+#include <dpl/assert.h>
+#include <pcrecpp.h>
+
+//WRT INCLUDES
+#include <widget_install/task_certify.h>
+#include <widget_install/job_widget_install.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include "wac_widget_id.h"
+
+#include <vcore/Certificate.h>
+#include <vcore/SignatureReader.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/WrtSignatureValidator.h>
+#include <pkgmgr-info.h>
+#include <dpl/utils/wrt_global_settings.h>
+
+#include <ITapiModem.h>
+#include <tapi_common.h>
+
+#include <installer_log.h>
+
+using namespace ValidationCore;
+using namespace WrtDB;
+
+namespace {
+const int SIGNATURE_FILE_NUMBER_DISTRIBUTOR1 = 1;
+const int SIGNATURE_FILE_NUMBER_DISTRIBUTOR2 = 2;
+
+WidgetCertificateData toWidgetCertificateData(const SignatureData &data,
+                                              bool root)
+{
+    WidgetCertificateData result;
+
+    result.chainId = data.getSignatureNumber();
+    _D("result.chainId : %d", result.chainId);
+
+    result.owner = data.isAuthorSignature() ?
+        WidgetCertificateData::AUTHOR : WidgetCertificateData::DISTRIBUTOR;
+
+    if (data.isAuthorSignature()) {
+        result.owner = WidgetCertificateData::AUTHOR;
+    } else {
+        if (SIGNATURE_FILE_NUMBER_DISTRIBUTOR1 == data.getSignatureNumber()) {
+            result.owner = WidgetCertificateData::DISTRIBUTOR;
+        } else if (SIGNATURE_FILE_NUMBER_DISTRIBUTOR2 ==
+                data.getSignatureNumber()){
+            result.owner = WidgetCertificateData::DISTRIBUTOR2;
+        } else {
+            result.owner = WidgetCertificateData::UNKNOWN;
+        }
+    }
+
+    result.type = root ?
+        WidgetCertificateData::ROOT : WidgetCertificateData::ENDENTITY;
+
+    CertificatePtr certificate;
+
+    if (root) {
+        certificate = data.getRootCaCertificatePtr();
+    } else {
+        certificate = data.getEndEntityCertificatePtr();
+    }
+
+    AssertMsg(certificate && !!certificate->getCommonName(),
+           "CommonName is Null");
+
+    result.strCommonName = *certificate->getCommonName();
+
+    result.strMD5Fingerprint = std::string("md5 ") +
+        Certificate::FingerprintToColonHex(
+            certificate->getFingerprint(Certificate::FINGERPRINT_MD5));
+
+    result.strSHA1Fingerprint = std::string("sha-1 ") +
+        Certificate::FingerprintToColonHex(
+            certificate->getFingerprint(Certificate::FINGERPRINT_SHA1));
+
+    return result;
+}
+
+CertificatePtr getOldAuthorSignerCertificate(DPL::String appid)
+{
+    CertificateChainList chainList;
+    WidgetDAOReadOnly dao(appid);
+    chainList = dao.getWidgetCertificate(SIGNATURE_AUTHOR);
+    FOREACH(it, chainList)
+    {
+        ValidationCore::CertificateCollection chain;
+        if (false == chain.load(*it)) {
+            _E("Chain is broken");
+        }
+
+        if (!chain.sort()) {
+            _E("Chain failed at sorting");
+        }
+
+        ValidationCore::CertificateList list = chain.getCertificateList();
+
+        FOREACH(cert, list)
+        {
+            if (!(*cert)->isRootCert() && !(*cert)->isCA()) {
+                return *cert;
+            }
+        }
+    }
+    return CertificatePtr();
+}
+} // namespace anonymous
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskCertify::TaskCertify(InstallerContext &inCont) :
+    DPL::TaskDecl<TaskCertify>(this),
+    m_contextData(inCont)
+{
+    AddStep(&TaskCertify::StartStep);
+    AddStep(&TaskCertify::stepSignature);
+    // certi comparison determines whether the update.
+    if (true == m_contextData.isUpdateMode) {
+        AddStep(&TaskCertify::stepVerifyUpdate);
+    }
+    AddStep(&TaskCertify::EndStep);
+}
+
+void TaskCertify::processDistributorSignature(const SignatureData &data)
+{
+    // this signature is verified -
+    // no point in check domain WAC_ROOT and WAC_RECOGNIZED
+    m_contextData.widgetSecurity.setDistributorSigned(true);
+
+    CertificateCollection collection;
+    collection.load(data.getCertList());
+    AssertMsg(collection.sort(),
+           "Certificate collection can't sort");
+
+    AssertMsg(collection.isChain(),
+           "Certificate collection is not able to create chain. "
+           "It is not possible to verify this signature.");
+
+    if (SIGNATURE_FILE_NUMBER_DISTRIBUTOR1 == data.getSignatureNumber()) {
+        m_contextData.widgetSecurity.getCertificateChainListRef().push_back(
+                collection);
+    } else {
+        m_contextData.widgetSecurity.getCertificateChainList2Ref().push_back(
+                collection);
+    }
+
+    m_contextData.widgetSecurity.getCertificateListRef().push_back(
+            toWidgetCertificateData(data, true));
+    m_contextData.widgetSecurity.getCertificateListRef().push_back(
+            toWidgetCertificateData(data, false));
+}
+
+void TaskCertify::processAuthorSignature(const SignatureData &data)
+{
+    using namespace ValidationCore;
+    _D("DNS Identity match!");
+    // this signature is verified or widget is distributor signed
+    m_contextData.widgetSecurity.setAuthorCertificatePtr(data.getEndEntityCertificatePtr());
+    CertificatePtr test = m_contextData.widgetSecurity.getAuthorCertificatePtr();
+
+    m_contextData.widgetSecurity.getCertificateListRef().push_back(
+        toWidgetCertificateData(data, true));
+    m_contextData.widgetSecurity.getCertificateListRef().push_back(
+        toWidgetCertificateData(data, false));
+
+    // match widget_id with one from dns identity set
+    WacWidgetId widgetId(m_contextData.widgetConfig.configInfo.widget_id);
+
+    CertificatePtr cert = data.getEndEntityCertificatePtr();
+    Assert(cert);
+    Certificate::AltNameSet dnsIdentity = cert->getAlternativeNameDNS();
+
+    CertificateCollection collection;
+    collection.load(data.getCertList());
+    collection.sort();
+    AssertMsg(collection.isChain(),
+           "Certificate collection is not able to create chain. "
+           "It is not possible to verify this signature.");
+
+    m_contextData.widgetSecurity.getAuthorsCertificateChainListRef().push_back(
+        collection);
+
+    FOREACH(it, dnsIdentity){
+        if (widgetId.matchHost(*it)) {
+            m_contextData.widgetSecurity.setRecognized(true);
+            return;
+        }
+    }
+}
+
+void TaskCertify::getSignatureFiles(std::string path, SignatureFileInfoSet& file)
+{
+    _D("path : %s", path.c_str());
+    SignatureFileInfoSet signatureFiles;
+    SignatureFinder signatureFinder(path);
+    if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
+        _E("Error in Signature Finder : %s", path.c_str());
+        ThrowMsg(Exceptions::SignatureNotFound,
+                "Error openig temporary widget directory");
+    }
+}
+
+void TaskCertify::stepSignature()
+{
+    LOGD("================ Step: <<Signature>> ENTER ===============");
+
+    std::string widgetPath;
+    widgetPath = m_contextData.locations->getPackageInstallationDir() + "/";
+
+    SignatureFileInfoSet signatureFiles;
+
+    Try {
+        getSignatureFiles(widgetPath, signatureFiles);
+
+        if (signatureFiles.size() <= 0) {
+            widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
+                + "/";
+            if (0 == access(widgetPath.c_str(), F_OK)) {
+                getSignatureFiles(widgetPath, signatureFiles);
+            }
+        }
+    } Catch(Exceptions::SignatureNotFound) {
+        ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
+    }
+
+    SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
+    _D("Number of signatures: %d", signatureFiles.size());
+
+    for (; iter != signatureFiles.rend(); ++iter) {
+        _D("Checking signature with id=%d", iter->getFileNumber());
+        SignatureData data(widgetPath + iter->getFileName(),
+                           iter->getFileNumber());
+
+        Try {
+            SignatureReader xml;
+            xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
+            xml.read(data);
+
+            WrtSignatureValidator::Result result;
+
+            WrtSignatureValidator validator(
+                    WrtSignatureValidator::TIZEN,
+                    !GlobalSettings::
+                    OCSPTestModeEnabled(),
+                    !GlobalSettings::
+                    CrlTestModeEnabled(),
+                    false);
+
+            result = validator.check(data, widgetPath);
+
+            if (m_contextData.mode.installTime == InstallMode::InstallTime::PRELOAD
+                || m_contextData.mode.command == InstallMode::Command::RECOVERY
+                    || m_contextData.mode.installTime == InstallMode::InstallTime::FOTA)
+            {
+                result = WrtSignatureValidator::SIGNATURE_VERIFIED;
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
+                _W("Certificate is REVOKED");
+                ThrowMsg(Exceptions::CertificateExpired,
+                         "Certificate is REVOKED");
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
+                    iter->getFileNumber() <= 1) {
+                _W("Signature is INVALID");
+                // TODO change exception name
+                ThrowMsg(Exceptions::SignatureInvalid,
+                         "Invalid Package");
+            }
+
+            if (data.isAuthorSignature()) {
+                if (result == WrtSignatureValidator::SIGNATURE_VERIFIED ) {
+                    processAuthorSignature(data);
+                }
+            } else {
+                if (result != WrtSignatureValidator::SIGNATURE_INVALID) {
+                    processDistributorSignature(data);
+                }
+            }
+        } Catch(ParserSchemaException::Base) {
+            _E("Error occured in ParserSchema.");
+            ReThrowMsg(Exceptions::SignatureInvalid,
+                       "Error occured in ParserSchema.");
+        }
+    }
+
+    if (signatureFiles.empty()) {
+        _D("No signature files has been found.");
+    }
+
+    LOGD("================ Step: <<Signature>> DONE ================");
+
+    m_contextData.job->UpdateProgress(
+        InstallerContext::INSTALL_DIGSIG_CHECK,
+        "Widget Signature checked");
+}
+
+bool TaskCertify::isTizenWebApp() const
+{
+    bool ret = FALSE;
+    if (m_contextData.widgetConfig.webAppType.appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
+    {
+        ret = TRUE;
+    }
+
+    return ret;
+}
+
+void TaskCertify::stepVerifyUpdate()
+{
+    LOGD("================ Step: <<VerifyUpdate>> ENTER ===============");
+
+    std::string oldAuthorCert;
+
+    int ret = 0;
+    pkgmgrinfo_certinfo_h handle;
+    const char *authorCert = NULL;
+    ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
+    if (PMINFO_R_OK == ret) {
+        ret = pkgmgrinfo_pkginfo_load_certinfo(DPL::ToUTF8String(
+                    m_contextData.widgetConfig.tzPkgid).c_str(), handle);
+        if (PMINFO_R_OK == ret) {
+            ret = pkgmgrinfo_pkginfo_get_cert_value(handle,
+                    PMINFO_AUTHOR_SIGNER_CERT, &authorCert);
+            if (PMINFO_R_OK == ret) {
+                oldAuthorCert = (NULL != authorCert)? authorCert : "";
+            }
+        }
+        pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+    }
+
+    if (oldAuthorCert.empty()) {
+        _D("Old cert is empty.");
+    } else {
+        ValidationCore::CertificatePtr certPtr = m_contextData.widgetSecurity.getAuthorCertificatePtr();
+        if (certPtr == NULL) {
+            ThrowMsg(Exceptions::NotMatchedCertification, "No author certificates");
+        }
+
+        DPL::String newAuthorPublicKeyStr = certPtr->getPublicKeyString();
+        //compare with public key
+        ValidationCore::Certificate installedCert(oldAuthorCert , ValidationCore::Certificate::FORM_BASE64);
+        DPL::String installedPublicKeyStr = installedCert.getPublicKeyString();
+        if (0 != installedPublicKeyStr.compare(newAuthorPublicKeyStr)) {
+            _D("old widget's author public key : %ls",
+                    installedPublicKeyStr.c_str());
+            _D("new widget's author public key: %ls",
+                    newAuthorPublicKeyStr.c_str());
+            ThrowMsg(Exceptions::NotMatchedCertification,
+                    "Author signer certificates doesn't match \
+                    between old widget and installing widget");
+        }
+
+    }
+    LOGD("================ Step: <<VerifyUpdate>> DONE ===============");
+}
+
+void TaskCertify::StartStep()
+{
+    LOGD("--------- <TaskCertify> : START ----------");
+}
+
+void TaskCertify::EndStep()
+{
+    LOGD("Step: <<CERTYFYING DONE>>");
+
+    m_contextData.job->UpdateProgress(
+        InstallerContext::INSTALL_CERT_CHECK,
+        "Widget Certification Check Finished");
+
+    LOGD("--------- <TaskCertify> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
+
diff --git a/src_wearable/jobs/widget_install/task_certify.h b/src_wearable/jobs/widget_install/task_certify.h
new file mode 100644 (file)
index 0000000..6a59781
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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>
+#include <vcore/SignatureFinder.h>
+
+//WRT INCLUDES
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace ValidationCore {
+class SignatureData;
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskCertify :
+    public DPL::TaskDecl<TaskCertify>
+{
+  public:
+    TaskCertify(InstallerContext &inCont);
+
+  private:
+    //data
+    InstallerContext& m_contextData;
+
+    //steps
+    void stepSignature();
+    void stepVerifyUpdate();
+
+    void StartStep();
+    void EndStep();
+
+    void processDistributorSignature(const ValidationCore::SignatureData &data);
+    void processAuthorSignature(const ValidationCore::SignatureData &data);
+    void getSignatureFiles(std::string path,
+            ValidationCore::SignatureFileInfoSet& file);
+
+    bool isTizenWebApp() const;
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_H
diff --git a/src_wearable/jobs/widget_install/task_certify_level.cpp b/src_wearable/jobs/widget_install/task_certify_level.cpp
new file mode 100755 (executable)
index 0000000..1b9bffe
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2013 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_level.cpp
+ * @author  Jihoon Chung (jihoon.chung@samgsung.com)
+ * @version
+ * @brief
+ */
+
+//SYSTEM INCLUDES
+#include <string>
+#include <map>
+#include <unistd.h>
+
+//WRT INCLUDES
+#include <widget_install/task_certify_level.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/string.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <vcore/CertStoreType.h>
+#include <vcore/SignatureReader.h>
+#include <vcore/SignatureFinder.h>
+#include <vcore/WrtSignatureValidator.h>
+#include <dpl/utils/wrt_global_settings.h>
+
+#include <installer_log.h>
+
+using namespace ValidationCore;
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskCertifyLevel::TaskCertifyLevel(InstallerContext &inCont) :
+    DPL::TaskDecl<TaskCertifyLevel>(this),
+    m_contextData(inCont)
+{
+    AddStep(&TaskCertifyLevel::StartStep);
+    AddStep(&TaskCertifyLevel::stepCertifyLevel);
+    AddStep(&TaskCertifyLevel::EndStep);
+}
+
+void TaskCertifyLevel::stepCertifyLevel()
+{
+    LOGD("================ Step: <<Certify Level>> ENTER ===============");
+    if (!checkConfigurationLevel(getCertifyLevel())) {
+        ThrowMsg(Exceptions::PrivilegeLevelViolation, "setting level violate");
+    }
+    LOGD("================ Step: <<Certify Level>> DONE ================");
+}
+
+void TaskCertifyLevel::getSignatureFiles(const std::string& path,
+                                         SignatureFileInfoSet& file)
+{
+    SignatureFileInfoSet signatureFiles;
+    SignatureFinder signatureFinder(path);
+    if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) {
+        _E("Error in Signature Finder : %s", path.c_str());
+        ThrowMsg(Exceptions::SignatureNotFound, "Signature not found");
+    }
+}
+
+TaskCertifyLevel::Level TaskCertifyLevel::getCertifyLevel()
+{
+    std::string widgetPath = m_contextData.locations->getPackageInstallationDir() + "/";
+    SignatureFileInfoSet signatureFiles;
+
+    Try {
+        getSignatureFiles(widgetPath, signatureFiles);
+
+        if (signatureFiles.size() <= 0) {
+            widgetPath += std::string(WrtDB::GlobalConfig::GetWidgetSrcPath())
+                + "/";
+            if (0 == access(widgetPath.c_str(), F_OK)) {
+                getSignatureFiles(widgetPath, signatureFiles);
+            }
+        }
+    } Catch(Exceptions::SignatureNotFound) {
+        ReThrowMsg(Exceptions::SignatureNotFound, widgetPath);
+    }
+
+    SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin();
+    _D("Number of signatures: %d", signatureFiles.size());
+
+    Level level = Level::UNKNOWN;
+    for (; iter != signatureFiles.rend(); ++iter) {
+        _D("Checking signature with id=%d", iter->getFileNumber());
+        SignatureData data(widgetPath + iter->getFileName(),
+                           iter->getFileNumber());
+
+        Try {
+            SignatureReader xml;
+            xml.initialize(data, GlobalConfig::GetSignatureXmlSchema());
+            xml.read(data);
+
+            WrtSignatureValidator validator(
+                    WrtSignatureValidator::TIZEN,
+                    !GlobalSettings::
+                    OCSPTestModeEnabled(),
+                    !GlobalSettings::
+                    CrlTestModeEnabled(),
+                    false);
+
+            WrtSignatureValidator::Result result =
+                validator.check(data, widgetPath);
+
+            if (m_contextData.mode.installTime == InstallMode::InstallTime::PRELOAD
+                    || m_contextData.mode.command == InstallMode::Command::RECOVERY
+                    || m_contextData.mode.installTime == InstallMode::InstallTime::FOTA)
+            {
+                result = WrtSignatureValidator::SIGNATURE_VERIFIED;
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_REVOKED) {
+                ThrowMsg(Exceptions::CertificateExpired,
+                         "Certificate is REVOKED");
+            }
+
+            if (result == WrtSignatureValidator::SIGNATURE_INVALID &&
+                    iter->getFileNumber() <= 1)
+            {
+                ThrowMsg(Exceptions::SignatureInvalid, "Invalid Package");
+            }
+
+            if (data.isAuthorSignature()) {
+                _D("Skip author signature");
+            } else {
+                Level currentCertLevel =
+                    certTypeToLevel(data.getVisibilityLevel());
+                if (currentCertLevel == Level::UNKNOWN) {
+                    continue;
+                }
+                if (currentCertLevel > level) {
+                    level = currentCertLevel;
+                    _D("level %s", enumToString(level).c_str());
+                }
+            }
+        } Catch(ParserSchemaException::Base) {
+            _E("Error occured in ParserSchema.");
+            ReThrowMsg(Exceptions::SignatureInvalid,
+                       "Error occured in ParserSchema.");
+        }
+    }
+
+    m_contextData.certLevel = level;
+    return level;
+}
+
+bool TaskCertifyLevel::checkConfigurationLevel(
+    TaskCertifyLevel::Level level)
+{
+    if (!checkSettingLevel(level)) {
+        return false;
+    }
+    if (!checkAppcontrolHasDisposition(level)) {
+        return false;
+    }
+    if (!checkServiceLevel(level)) {
+        return false;
+    }
+    return true;
+}
+
+bool TaskCertifyLevel::checkSettingLevel(
+    TaskCertifyLevel::Level level)
+{
+    secureSettingMap data = {
+        {"sound-mode", Level::PARTNER},
+        {"nodisplay", Level::PARTNER}
+    };
+    FOREACH(it, m_contextData.widgetConfig.configInfo.settingsList) {
+        secureSettingIter ret = data.find(DPL::ToUTF8String(it->m_name));
+        if (ret != data.end()) {
+            if (level < ret->second) {
+                _E("\"%ls\" needs \"%s\" level", it->m_name.c_str(), enumToString(ret->second).c_str());
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+bool TaskCertifyLevel::checkAppcontrolHasDisposition(
+    TaskCertifyLevel::Level level)
+{
+    // tizen:disposition -> platform
+    FOREACH(it, m_contextData.widgetConfig.configInfo.appControlList) {
+        if (ConfigParserData::AppControlInfo::Disposition::UNDEFINE !=
+            it->m_disposition)
+        {
+            if (level < Level::PLATFORM) {
+                _E("\"tizen:disposition\" needs \"%s \" level", enumToString(Level::PLATFORM).c_str());
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+bool TaskCertifyLevel::checkServiceLevel(
+    TaskCertifyLevel::Level level)
+{
+    if (m_contextData.widgetConfig.configInfo.serviceAppInfoList.size() > 0) {
+        if (level < Level::PARTNER) {
+            _E("\"tizen:service\" needs \"%s \" level", enumToString(Level::PARTNER).c_str());
+            return false;
+        }
+    }
+    return true;
+}
+
+std::string TaskCertifyLevel::enumToString(
+    TaskCertifyLevel::Level level)
+{
+    switch (level) {
+#define X(x, y) case x: return #y;
+        X(Level::UNKNOWN, UNKNOWN)
+        X(Level::PUBLIC, PUBLIC)
+        X(Level::PARTNER, PARTNER)
+        X(Level::PLATFORM, PLATFORM)
+#undef X
+    default:
+        return "UNKNOWN";
+    }
+}
+
+TaskCertifyLevel::Level TaskCertifyLevel::certTypeToLevel(
+    CertStoreId::Type type)
+{
+    // CertStoreType.h (framework/security/cert-svc)
+    // RootCA's visibility level : public
+    // const Type VIS_PUBLIC = 1 << 6;
+    // RootCA's visibility level : partner
+    // const Type VIS_PARTNER = 1 << 7;
+    // RootCA's visibility level : platform
+    // const Type VIS_PLATFORM = 1 << 10;
+    if (type == CertStoreId::VIS_PUBLIC) {
+        return Level::PUBLIC;
+    } else if (type == CertStoreId::VIS_PARTNER) {
+        return Level::PARTNER;
+    } else if (type == CertStoreId::VIS_PLATFORM) {
+        return Level::PLATFORM;
+    }
+    return Level::UNKNOWN;
+}
+
+void TaskCertifyLevel::StartStep()
+{
+    LOGD("--------- <TaskCertifyLevel> : START ----------");
+}
+
+void TaskCertifyLevel::EndStep()
+{
+    LOGD("--------- <TaskCertifyLevel> : END ----------");
+
+    m_contextData.job->UpdateProgress(
+        InstallerContext::INSTALL_CERTIFY_LEVEL_CHECK,
+        "Application Certificate level check Finished");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
+
diff --git a/src_wearable/jobs/widget_install/task_certify_level.h b/src_wearable/jobs/widget_install/task_certify_level.h
new file mode 100755 (executable)
index 0000000..004ecbb
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013 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_level.h
+ * @author  Jihoon Chung (jihoon.chung@samgsung.com)
+ * @version
+ * @brief
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_LEVEL_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_LEVEL_H
+
+//SYSTEM INCLUDES
+#include <string>
+#include <cstdint>
+#include <map>
+
+//WRT INCLUDES
+#include <vcore/CertStoreType.h>
+#include <vcore/SignatureFinder.h>
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskCertifyLevel :
+    public DPL::TaskDecl<TaskCertifyLevel>
+{
+  public:
+    TaskCertifyLevel(InstallerContext &inCont);
+
+  private:
+    //data
+    InstallerContext& m_contextData;
+
+    enum Level {
+        UNKNOWN  = 0,
+        PUBLIC   = 1,
+        PARTNER  = 2,
+        PLATFORM = 3
+    };
+    typedef std::map<std::string, Level> secureSettingMap;
+    typedef std::map<std::string, Level>::iterator secureSettingIter;
+
+    //steps
+    void stepCertifyLevel();
+    void StartStep();
+    void EndStep();
+
+    //util
+    void getSignatureFiles(const std::string& path,
+                           ValidationCore::SignatureFileInfoSet& file);
+    Level getCertifyLevel();
+    bool checkConfigurationLevel(Level level);
+    bool checkSettingLevel(Level level);
+    bool checkAppcontrolHasDisposition(Level level);
+    bool checkServiceLevel(Level level);
+    std::string enumToString(Level level);
+    Level certTypeToLevel(ValidationCore::CertStoreId::Type type);
+
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_CERTIFY_LEVEL_H
diff --git a/src_wearable/jobs/widget_install/task_commons.cpp b/src_wearable/jobs/widget_install/task_commons.cpp
new file mode 100644 (file)
index 0000000..c5b5b67
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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_commons.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include "task_commons.h"
+#include <unistd.h>
+#include <sstream>
+#include <ftw.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+#include <dpl/utils/wrt_utility.h>
+#include <widget_install/widget_install_errors.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace {
+const char * const TEMPORARY_PATH_POSTFIX = "temp";
+const mode_t TEMPORARY_PATH_MODE = 0775;
+} // namespace
+
+std::string createTempPath(bool preload)
+{
+    _D("Step: Creating temporary path");
+
+    // Temporary path
+    std::ostringstream tempPathBuilder;
+
+    if (preload) {
+        tempPathBuilder << WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+    } else {
+        tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    }
+    tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
+    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;
+
+    if (stat(tempPath.c_str(), &fileInfo) == 0) {
+        if (!WrtUtilRemove(tempPath)) {
+            ThrowMsg(Exceptions::RemovingFolderFailure,
+                     "Failed to to remove temporary directory");
+        }
+    }
+    // Create new path
+    if (!WrtUtilMakeDir(tempPath, TEMPORARY_PATH_MODE)) {
+        ThrowMsg(Exceptions::FileOperationFailed,
+                 "Failed to create temporary directory");
+    }
+
+    return tempPath;
+}
+
+void createTempPath(const std::string& path)
+{
+    if (!WrtUtilMakeDir(path, TEMPORARY_PATH_MODE)) {
+        ThrowMsg(Exceptions::FileOperationFailed,
+                 "Failed to create temporary directory");
+    }
+}
+} // WidgetInstall
+} // Jobs
diff --git a/src_wearable/jobs/widget_install/task_commons.h b/src_wearable/jobs/widget_install/task_commons.h
new file mode 100644 (file)
index 0000000..caf9660
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_commons.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_COMMONS_H_
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_COMMONS_H_
+
+#include <string>
+
+namespace Jobs {
+namespace WidgetInstall {
+//TODO make directory like jobs common?
+
+std::string createTempPath(bool isReadOnly = false);
+void createTempPath(const std::string& path);
+} // WidgetInstall
+} // Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_COMMONS_H_ */
diff --git a/src_wearable/jobs/widget_install/task_configuration.cpp b/src_wearable/jobs/widget_install/task_configuration.cpp
new file mode 100755 (executable)
index 0000000..fa3e0fa
--- /dev/null
@@ -0,0 +1,610 @@
+/*
+ * Copyright (c) 2013 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_configuration.cpp
+ * @version 1.0
+ * @author  Tomasz Iwanek
+ * @brief   implementation file for configuration task
+ */
+#include "task_configuration.h"
+
+#include <string>
+#include <sstream>
+#include <memory>
+#include <sys/time.h>
+#include <unistd.h>
+#include <ctime>
+#include <cstdlib>
+#include <limits.h>
+#include <regex.h>
+#include <vconf.h>
+#include <web_provider_service.h>
+
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/localization/w3c_file_localization.h>
+#include <pkgmgr-info.h>
+
+#include <libiriwrapper.h>
+#include <app_manager.h>
+
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install_to_external.h>
+#include <widget_install/widget_unzip.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_commons.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const char* const CONFIG_XML = "config.xml";
+const char* const WITH_OSP_XML = "res/wgt/config.xml";
+const char* const OSP_MANIFEST_XML = "info/manifest.xml";
+const char* const WRT_WIDGETS_XML_SCHEMA = "/usr/etc/wrt-installer/widgets.xsd";
+
+//allowed: a-z, A-Z, 0-9
+const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$";
+const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
+const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$";
+const size_t PACKAGE_ID_LENGTH = 10;
+
+static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
+static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
+static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = L"install-location";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = L"prefer-external";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_AUTO = L"auto";
+const std::string XML_EXTENSION = ".xml";
+
+bool hasExtension(const std::string& filename, const std::string& extension)
+{
+    _D("Looking for extension %s in %s", extension.c_str(), filename.c_str());
+    size_t fileLen = filename.length();
+    size_t extLen = extension.length();
+    if (fileLen < extLen) {
+        _E("Filename %s is shorter than extension %s", filename.c_str(), extension.c_str());
+        return false;
+    }
+    return (0 == filename.compare(fileLen - extLen, extLen, extension));
+}
+} // namespace anonymous
+
+namespace Jobs {
+namespace WidgetInstall {
+
+TaskConfiguration::TaskConfiguration(InstallerContext& context) :
+    DPL::TaskDecl<TaskConfiguration>(this),
+    m_context(context),
+    m_widgetConfig(m_context.widgetConfig.configInfo)
+{
+    AddStep(&TaskConfiguration::StartStep);
+
+    AddStep(&TaskConfiguration::SetupTempDirStep);
+    AddStep(&TaskConfiguration::UnzipConfigurationStep);
+    AddStep(&TaskConfiguration::ParseXMLConfigStep);
+
+    AddStep(&TaskConfiguration::TizenIdStep);
+    AddStep(&TaskConfiguration::ApplicationTypeStep);
+    AddStep(&TaskConfiguration::ResourceEncryptionStep);
+    AddStep(&TaskConfiguration::InstallationFSLocationStep);
+
+    AddStep(&TaskConfiguration::DetectUpdateInstallationStep);
+    AddStep(&TaskConfiguration::CheckRDSSupportStep);
+    AddStep(&TaskConfiguration::ConfigureWidgetLocationStep);
+    AddStep(&TaskConfiguration::PkgmgrStartStep);
+
+    AddStep(&TaskConfiguration::AppendTasklistStep);
+
+    AddStep(&TaskConfiguration::EndStep);
+}
+
+void TaskConfiguration::StartStep()
+{
+    LOGD("--------- <TaskConfiguration> : START ----------");
+}
+
+void TaskConfiguration::EndStep()
+{
+    m_context.job->UpdateProgress(InstallerContext::INSTALL_PARSE_CONFIG,
+            "Parse config.xml and set structure");
+    LOGD("--------- <TaskConfiguration> : END ----------");
+}
+
+void TaskConfiguration::PkgmgrStartStep()
+{
+    pkgMgrInterface()->setPkgname(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid));
+    pkgMgrInterface()->sendProgress(0);
+}
+
+void TaskConfiguration::AppendTasklistStep()
+{
+    switch(m_context.widgetConfig.webAppType.appType)
+    {
+        case APP_TYPE_TIZENWEBAPP:
+            if (m_context.mode.installTime == InstallMode::InstallTime::FOTA) {
+                if (!m_context.isUpdateMode) {
+                    _D("TaskConfiguration -> fota installation task list");
+                    m_context.job->appendFotaInstallationTaskList();
+                } else {
+                    _D("TaskConfiguration -> fota update task list");
+                    m_context.job->appendFotaUpdateTaskList();
+                }
+            } else {
+                if (!m_context.isUpdateMode) {
+                    _D("TaskConfiguration -> new installation task list");
+                    m_context.job->appendNewInstallationTaskList();
+                } else {
+                    if (m_context.mode.command == InstallMode::Command::REINSTALL) {
+                        _D("TaskConfiguration -> rds update task list");
+                        m_context.job->appendRDSUpdateTaskList();
+                    } else if(m_context.mode.command == InstallMode::Command::RECOVERY) {
+                        _D("TaskConfiguration -> recovery task list");
+                        m_context.job->appendRecoveryTaskList();
+                    } else {
+                        _D("TaskConfiguration -> update installation task list");
+                        m_context.job->appendUpdateInstallationTaskList();
+                    }
+                }
+            }
+            break;
+        default:
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid, "Unknown application type");
+    }
+}
+
+std::shared_ptr<PackageManager::IPkgmgrSignal> TaskConfiguration::pkgMgrInterface()
+{
+    return m_context.job->GetInstallerStruct().pkgmgrInterface;
+}
+
+void TaskConfiguration::SetupTempDirStep()
+{
+    _D("widgetPath: %s", m_context.requestedPath.c_str());
+    _D("tempPath: %s", m_tempDir.c_str());
+    if (m_context.mode.extension == InstallMode::ExtensionType::DIR) {
+        if (m_context.mode.command ==
+                InstallMode::Command::REINSTALL) {
+            std::ostringstream tempPathBuilder;
+            tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+            tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath();
+            tempPathBuilder << "/";
+            tempPathBuilder << m_context.requestedPath;
+            m_tempDir = tempPathBuilder.str();
+        } else if(m_context.mode.command == InstallMode::Command::RECOVERY) {
+            m_tempDir = Jobs::WidgetInstall::createTempPath(false);
+        } else {
+            m_tempDir = m_context.requestedPath;
+        }
+    } else {
+        m_tempDir =
+            Jobs::WidgetInstall::createTempPath(
+                    m_context.mode.rootPath ==
+                        InstallMode::RootPath::RO);
+    }
+}
+
+void TaskConfiguration::UnzipConfigurationStep()
+{
+    _D("UnzipConfigurationStep");
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR) {
+        if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files
+        {
+            WidgetUnzip wgtUnzip(m_context.requestedPath);
+            wgtUnzip.unzipConfiguration(m_tempDir, &m_context.widgetConfig.packagingType);
+            m_configuration += m_tempDir + "/" + CONFIG_XML;
+        } else{
+            m_context.widgetConfig.packagingType = PKG_TYPE_HOSTED_WEB_APP;
+            m_configuration += m_context.requestedPath;
+        }
+    } else {
+        std::string configFile = m_tempDir + "/" + CONFIG_XML;
+        std::string manifestFile = m_tempDir + "/";
+        if (!WrtUtilFileExists(configFile)) {
+            configFile = m_tempDir + "/" + WITH_OSP_XML;
+            if (!WrtUtilFileExists(configFile)) {
+                std::string tzAppId = m_context.requestedPath.
+                    substr(m_context.requestedPath.find_last_of("/")+1);
+                Try {
+                    WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTizenAppId(DPL::FromUTF8String(tzAppId)));
+                    configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+                    configFile += "/";
+                    manifestFile = configFile;
+                    configFile += WITH_OSP_XML;
+                }
+                Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+                {
+                    _E("Given tizenId not found in database");
+                    ThrowMsg(Exceptions::DatabaseFailure, "Given tizenId not found in database");
+                }
+            }
+        }
+        m_context.widgetConfig.packagingType = PKG_TYPE_NOMAL_WEB_APP;
+        manifestFile += OSP_MANIFEST_XML;
+
+        if (WrtUtilFileExists(manifestFile)) {
+            m_context.widgetConfig.packagingType = PKG_TYPE_HYBRID_WEB_APP;
+        }
+        m_configuration = configFile;
+    }
+    _D("m_configuration : %s", m_configuration.c_str());
+    _D("Package Type : %s", m_context.widgetConfig.packagingType.getPkgtypeToString().c_str());
+}
+
+void TaskConfiguration::ParseXMLConfigStep()
+{
+    _D("ParseXMLConfigStep");
+    // Parse config
+    ParserRunner parser;
+    Try
+    {
+        _D("m_configuration : %s", m_configuration.c_str());
+        if(!DPL::Utils::Path(m_configuration).Exists())
+        {
+            ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
+        }
+
+#ifdef SCHEMA_VALIDATION_ENABLED
+        if(!parser.Validate(m_configuration, WRT_WIDGETS_XML_SCHEMA))
+        {
+            _E("Invalid configuration file - schema validation failed");
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Failed to parse config.xml file");
+        }
+#endif
+        parser.Parse(m_configuration,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(m_widgetConfig,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        _E("Failed to parse config.xml file");
+        ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Parser exeption");
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+    {
+        _E("Failed to find installed widget - give proper tizenId");
+        ThrowMsg(Exceptions::RDSDeltaFailure, "WidgetNotExist");
+    }
+    Catch(Exceptions::WidgetConfigFileNotFound){
+        _E("Failed to find config.xml");
+        ThrowMsg(Exceptions::MissingConfig, "Parser exeption");
+    }
+
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR) {
+        if (!WrtUtilRemove(m_configuration)) {
+            _E("Error occurs during removing %s", m_configuration.c_str());
+        }
+    }
+
+}
+
+void TaskConfiguration::TizenIdStep()
+{
+    bool shouldMakeAppid = false;
+    using namespace PackageManager;
+
+    if (!!m_widgetConfig.tizenAppId) {
+        _D("Setting tizenAppId provided in config.xml: %s", DPL::ToUTF8String(*m_widgetConfig.tizenAppId).c_str());
+
+        m_context.widgetConfig.tzAppid = *m_widgetConfig.tizenAppId;
+        //check package id.
+        if (!!m_widgetConfig.tizenPkgId) {
+            _D("Setting tizenPkgId provided in config.xml: %s", DPL::ToUTF8String(*m_widgetConfig.tizenPkgId).c_str());
+
+            m_context.widgetConfig.tzPkgid = *m_widgetConfig.tizenPkgId;
+        } else {
+            DPL::String appid = *m_widgetConfig.tizenAppId;
+            if (appid.length() > PACKAGE_ID_LENGTH) {
+                m_context.widgetConfig.tzPkgid =
+                    appid.substr(0, PACKAGE_ID_LENGTH);
+            } else {
+                //old version appid only has 10byte random character is able to install for a while.
+                //this case appid equal pkgid.
+                m_context.widgetConfig.tzPkgid =
+                    *m_widgetConfig.tizenAppId;
+                shouldMakeAppid = true;
+            }
+        }
+    } else {
+        shouldMakeAppid = true;
+        TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId();
+        _D("Checking if pkg id is unique");
+        while (true) {
+            if (!validateTizenPackageID(pkgId)) {
+                //path exist, chose another one
+                pkgId = WidgetDAOReadOnly::generatePkgId();
+                continue;
+            }
+            break;
+        }
+        m_context.widgetConfig.tzPkgid = pkgId;
+        _D("tizen_id name was generated by WRT: %ls", m_context.widgetConfig.tzPkgid.c_str());
+    }
+
+    if (shouldMakeAppid == true) {
+        DPL::OptionalString name;
+        DPL::OptionalString defaultLocale = m_widgetConfig.defaultlocale;
+
+        FOREACH(localizedData, m_widgetConfig.localizedDataSet)
+        {
+            Locale i = localizedData->first;
+            if (!!defaultLocale) {
+                if (defaultLocale == i) {
+                    name = localizedData->second.name;
+                    break;
+                }
+            } else {
+                name = localizedData->second.name;
+                break;
+            }
+        }
+        regex_t regx;
+        if (regcomp(&regx, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+            _D("Regcomp failed");
+        }
+
+        _D("Name : %ls", (*name).c_str());
+        if (!name || (regexec(&regx, DPL::ToUTF8String(*name).c_str(),
+                              static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
+        {
+            const std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+            std::ostringstream genName;
+            struct timeval tv;
+            gettimeofday(&tv, NULL);
+            unsigned int seed = time(NULL) + tv.tv_usec;
+
+            genName << "_" << allowedString[rand_r(&seed) % allowedString.length()];
+            name = DPL::FromUTF8String(genName.str());
+            _D("name was generated by WRT");
+        }
+        regfree(&regx);
+        _D("Name : %ls", (*name).c_str());
+        std::ostringstream genid;
+        genid << m_context.widgetConfig.tzPkgid << "." << (*name);
+        _D("tizen appid was generated by WRT : %s", genid.str().c_str());
+
+        DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
+        NormalizeAndTrimSpaceString(appid);
+        m_context.widgetConfig.tzAppid = *appid;
+    }
+
+    // send start signal of pkgmgr
+    pkgMgrInterface()->setPkgname(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid));
+
+    _D("Tizen App Id : %ls", (m_context.widgetConfig.tzAppid).c_str());
+    _D("Tizen Pkg Id : %ls", (m_context.widgetConfig.tzPkgid).c_str());
+}
+
+void TaskConfiguration::ConfigureWidgetLocationStep()
+{
+    m_context.locations =
+        WidgetLocation(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid),
+                       m_context.requestedPath, m_tempDir,
+                       m_context.widgetConfig.packagingType,
+                       m_context.mode.rootPath ==
+                           InstallMode::RootPath::RO,
+                           m_context.mode.extension);
+    m_context.locations->registerAppid(
+        DPL::ToUTF8String(m_context.widgetConfig.tzAppid));
+#ifdef SERVICE_ENABLED
+    FOREACH(it, m_context.widgetConfig.configInfo.serviceAppInfoList)
+    {
+        m_context.locations->registerServiceAppid(DPL::ToUTF8String(it->serviceId));
+    }
+#endif
+    _D("widgetSource %s", m_context.requestedPath.c_str());
+}
+
+void TaskConfiguration::DetectUpdateInstallationStep()
+{
+    pkgmgrinfo_pkginfo_h handle;
+
+    if (PMINFO_R_OK ==
+            pkgmgrinfo_pkginfo_get_pkginfo(DPL::ToUTF8String(
+                    m_context.widgetConfig.tzPkgid).c_str(), &handle)) {
+        // Update mode
+        m_context.isUpdateMode = true;
+        pkgMgrInterface()->startJob(InstallationType::UpdateInstallation);
+
+    } else {
+        // Install mode
+        m_context.isUpdateMode = false;
+        pkgMgrInterface()->startJob(InstallationType::NewInstallation);
+
+        if (!validateTizenApplicationID(m_context.widgetConfig.tzAppid)) {
+            _E("tizen application ID is invalid");
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
+                "invalid config");
+        }
+        if (!validateTizenPackageID(m_context.widgetConfig.tzPkgid)) {
+            _E("tizen package ID is invalid");
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid,
+                "invalid config");
+        }
+    }
+    OptionalWidgetVersion incomingVersion;
+    char *existingVersion = NULL;
+
+    if (!!m_widgetConfig.version) {
+        incomingVersion =
+            OptionalWidgetVersion(
+                WidgetVersion(*m_widgetConfig.version));
+        _D("incoming version = '%ls", incomingVersion->Raw().c_str());
+    }
+
+    if (m_context.isUpdateMode &&
+            PMINFO_R_OK == pkgmgrinfo_pkginfo_get_version(handle,
+                &existingVersion)) {
+        _D("existing version = %s", existingVersion);
+    }
+
+    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+}
+
+void TaskConfiguration::CheckRDSSupportStep()
+{
+    //update needs RDS support to go ahead if REINSTALL command is given
+    if(m_context.isUpdateMode)
+    {
+        if (!checkSupportRDSUpdateIfReinstall(m_widgetConfig)) {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate,
+                "RDS update failed");
+        }
+    }
+}
+
+bool TaskConfiguration::validateTizenApplicationID(
+    const WrtDB::TizenAppId &tizenAppId)
+{
+    _D("tizen application ID = [%ls]", tizenAppId.c_str());
+
+    regex_t reg;
+    if (regcomp(&reg, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+        _D("Regcomp failed");
+        return false;
+    }
+
+    if (regexec(&reg, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
+        == REG_NOMATCH)
+    {
+        regfree(&reg);
+        return false;
+    }
+    regfree(&reg);
+    return true;
+}
+
+bool TaskConfiguration::validateTizenPackageID(
+    const WrtDB::TizenPkgId &tizenPkgId)
+{
+    _D("tizen application ID = [%ls]", tizenPkgId.c_str());
+
+    regex_t reg;
+    if (regcomp(&reg, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0)
+    {
+        _D("Regcomp failed");
+        return false;
+    }
+    if (regexec(&reg, DPL::ToUTF8String(tizenPkgId).c_str(), 0, NULL, 0) == REG_NOMATCH)
+    {
+        regfree(&reg);
+        return false;
+    }
+    regfree(&reg);
+    return true;
+}
+
+void TaskConfiguration::ApplicationTypeStep() //TODO: is this really needed as WAC is not supported?
+{
+    AppType widgetAppType = APP_TYPE_UNKNOWN;
+    FOREACH(iterator, m_widgetConfig.nameSpaces) {
+        _D("namespace = [%ls]", (*iterator).c_str());
+
+        if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) {
+            widgetAppType = APP_TYPE_TIZENWEBAPP;
+            break;
+        }
+    }
+
+    m_context.widgetConfig.webAppType = widgetAppType;
+
+    _D("type = [%s]", m_context.widgetConfig.webAppType.getApptypeToString().c_str());
+}
+
+void TaskConfiguration::ResourceEncryptionStep()
+{
+    m_context.needEncryption = false;
+    FOREACH(it, m_widgetConfig.settingsList)
+    {
+        if (it->m_name == SETTING_VALUE_ENCRYPTION &&
+            it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
+        {
+            _D("resource need encryption");
+            m_context.needEncryption = true;
+        }
+    }
+}
+
+void TaskConfiguration::InstallationFSLocationStep()
+{
+    if (m_context.mode.installTime == InstallMode::InstallTime::NORMAL) {
+        FOREACH(it, m_widgetConfig.settingsList) {
+            if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME) {
+                if (it->m_value == SETTING_VALUE_INSTALLTOEXT_AUTO) {
+                    m_context.locationType = INSTALL_LOCATION_TYPE_AUTO;
+                } else if (it->m_value == SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) {
+                    m_context.locationType =
+                        INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
+                } else {
+                    m_context.locationType =
+                        INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+                }
+                break;
+            }
+        }
+    } else {
+        m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+    }
+}
+
+bool TaskConfiguration::checkSupportRDSUpdateIfReinstall(const WrtDB::ConfigParserData
+        &configInfo)
+{
+    if (m_context.mode.command ==
+            InstallMode::Command::REINSTALL)
+    {
+        DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
+        DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
+
+        WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid);
+        WrtDB::WidgetSettings widgetSettings;
+        dao.getWidgetSettings(widgetSettings);
+
+        FOREACH(it, widgetSettings) {
+            if (it->settingName == SETTING_VALUE_ENCRYPTION) {
+                dbValue = it->settingValue;
+            }
+        }
+
+        FOREACH(data, configInfo.settingsList)
+        {
+            if (data->m_name == SETTING_VALUE_ENCRYPTION)
+            {
+                configValue = data->m_value;
+            }
+        }
+        if (configValue != dbValue) {
+            _E("Not Support RDS mode because of encryption setting");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+}
+}
diff --git a/src_wearable/jobs/widget_install/task_configuration.h b/src_wearable/jobs/widget_install/task_configuration.h
new file mode 100644 (file)
index 0000000..879a8d3
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013 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_configuration.h
+ * @version 1.0
+ * @author  Tomasz Iwanek
+ * @brief   header file for configuration task
+ */
+#ifndef TASK_CONFIGURATION_H
+#define TASK_CONFIGURATION_H
+
+#include <string>
+
+#include <dpl/task.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+
+#include <widget_install/widget_install_context.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+#include <pkg-manager/pkgmgr_signal.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+class TaskConfiguration : public DPL::TaskDecl<TaskConfiguration>
+{
+    InstallerContext& m_context;
+    std::string m_tempDir;
+    WrtDB::ConfigParserData &m_widgetConfig;
+    std::string m_configuration;
+
+    void parseWidgetXMLConfig(
+        const std::string &widgetSource,
+        const std::string &tempPath,
+        WrtDB::PackagingType pkgType,
+        bool isReinstall);
+
+    bool validateTizenApplicationID(const WrtDB::TizenAppId &tizenAppId);
+    bool validateTizenPackageID(const WrtDB::TizenPkgId &tizenPkgId);
+    void ApplicationTypeStep(const WrtDB::ConfigParserData &configInfo);
+    bool checkSupportRDSUpdateIfReinstall(const WrtDB::ConfigParserData &configInfo);
+    bool getDefaultExternalStorage();
+    bool getMMCStatus();
+
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgMgrInterface();
+
+    //steps
+    void StartStep();
+
+    void SetupTempDirStep();
+    void UnzipConfigurationStep();
+    void ParseXMLConfigStep();
+
+    void TizenIdStep();
+    void DetectUpdateInstallationStep();
+    void PkgmgrStartStep();
+
+    void ApplicationTypeStep();
+    void ResourceEncryptionStep();
+    void InstallationFSLocationStep();
+
+    void ConfigureWidgetLocationStep();
+    void CheckRDSSupportStep();
+
+    void AppendTasklistStep();
+    void EndStep();
+
+public:
+    TaskConfiguration(InstallerContext& context);
+};
+
+}
+}
+
+#endif // TASK_CONFIGURATION_H
diff --git a/src_wearable/jobs/widget_install/task_database.cpp b/src_wearable/jobs/widget_install/task_database.cpp
new file mode 100755 (executable)
index 0000000..8b9660b
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+ * 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_new_db_insert.cpp
+ * @author  Lukasz Wrzosek(l.wrzosek@samsung.com)
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task database updating for widget
+ * update
+ */
+#include <unistd.h>
+#include <cstdio>
+#include <time.h>
+#include <sys/stat.h>
+#include <widget_install/task_database.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#ifdef DBOX_ENABLED
+#include <web_provider_livebox_info.h>
+#endif
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/assert.h>
+#include <wrt-commons/security-origin-dao/security_origin_dao.h>
+#include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_types.h>
+#include <string>
+#include <sstream>
+#include <ace_api_install.h>
+#include <ace_registration.h>
+#include <errno.h>
+#include <string.h>
+#include <map>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskDatabase::TaskDatabase(InstallerContext& context) :
+    DPL::TaskDecl<TaskDatabase>(this),
+    m_context(context)
+{
+    AddStep(&TaskDatabase::StartStep);
+    AddStep(&TaskDatabase::StepRegisterExternalFiles);
+    AddStep(&TaskDatabase::StepWrtDBInsert);
+    AddStep(&TaskDatabase::StepAceDBInsert);
+    AddStep(&TaskDatabase::StepSecurityOriginDBInsert);
+    AddStep(&TaskDatabase::StepWidgetInterfaceDBInsert);
+    AddStep(&TaskDatabase::StepRemoveExternalFiles);
+#ifdef DBOX_ENABLED
+    AddStep(&TaskDatabase::StepLiveboxDBInsert);
+#endif
+    AddStep(&TaskDatabase::EndStep);
+
+    AddAbortStep(&TaskDatabase::StepAbortDBInsert);
+    AddAbortStep(&TaskDatabase::StepAbortAceDBInsert);
+    AddAbortStep(&TaskDatabase::StepAbortWidgetInterfaceDBInsert);
+}
+
+void TaskDatabase::StepWrtDBInsert()
+{
+    Try
+    {
+        /* Set install Time */
+        time(&m_context.widgetConfig.installedTime);
+
+        if (m_context.isUpdateMode) { //update
+            _D("Registering widget... (update)");
+            Try
+            {
+                std::list<TizenAppId> idList = WidgetDAOReadOnly::getTzAppIdList(m_context.widgetConfig.tzPkgid);
+                FOREACH(it , idList ){
+                    //installed AppId list, It need to delete ACE Database corresponding record
+                    m_handleToRemoveList.push_back(WidgetDAOReadOnly::getHandle(*it));
+                    WrtDB::TizenAppId backAppId = *it + L".backup";
+                    m_backAppIdList.push_back(backAppId);
+                    //Change all installed tzAppid to .backup
+                    WidgetDAO::updateTizenAppId(*it, backAppId);
+            }
+
+            WidgetDAO::registerWidget(m_context.widgetConfig.tzAppid,
+                                      m_context.widgetConfig,
+                                      m_context.widgetSecurity);
+                m_handleList.push_back(WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid));
+
+                FOREACH(iterator, m_context.widgetConfig.configInfo.serviceAppInfoList) {
+                    WrtDB::TizenAppId tizenAppId = iterator->serviceId;
+                    WidgetDAO::registerService(*iterator, m_context.widgetConfig, m_context.widgetSecurity);
+                    m_handleList.push_back(WidgetDAOReadOnly::getHandle(tizenAppId));
+                }
+            }
+            Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+            {
+                LogError(
+                    "Given tizenId not found for update installation (Same GUID?)");
+                ThrowMsg(Exceptions::DatabaseFailure,
+                         "Given tizenId not found for update installation");
+            }
+        } else { //new installation
+            _D("Registering widget...");
+            WidgetDAO::registerWidget(
+                m_context.widgetConfig.tzAppid,
+                m_context.widgetConfig,
+                m_context.widgetSecurity);
+
+            m_handleList.push_back(WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid));
+
+            FOREACH(iterator, m_context.widgetConfig.configInfo.serviceAppInfoList) {
+                    WidgetDAO::registerService(*iterator, m_context.widgetConfig, m_context.widgetSecurity);
+                    m_handleList.push_back(WidgetDAOReadOnly::getHandle(iterator->serviceId));
+            }
+        }
+
+        FOREACH(cap, m_context.staticPermittedDevCaps) {
+            _D("staticPermittedDevCaps : %ls smack status: %d", cap->first.c_str(), cap->second);
+        }
+
+        _D("Widget registered");
+    }
+    Catch(WidgetDAO::Exception::DatabaseError)
+    {
+        _E("Database failure!");
+        ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!");
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base)
+    {
+        _E("Database failure!");
+        ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!");
+    }
+}
+
+void TaskDatabase::StepAceDBInsert()
+{
+    FOREACH(iterHandleToRemove, m_handleToRemoveList)
+    {
+        if (INVALID_WIDGET_HANDLE != *iterHandleToRemove) {
+            _D("Removing old insallation. Handle: %d", *iterHandleToRemove);
+            if (ACE_OK != ace_unregister_widget(
+                    static_cast<ace_widget_handle_t>(*iterHandleToRemove)))
+            {
+                _W("Error while removing ace entry for previous insallation");
+            }
+        }
+    }
+
+    FOREACH(iterHandle, m_handleList)
+    {
+        if (!AceApi::registerAceWidget(*iterHandle, m_context.widgetConfig,
+                                   m_context.widgetSecurity.getCertificateList()))
+        {
+            _E("ace database insert failed");
+            ThrowMsg(Exceptions::UpdateFailed,
+                 "Update failure. ace_register_widget failed");
+        }
+        _D("Ace data inserted");
+    }
+}
+
+void TaskDatabase::StepSecurityOriginDBInsert()
+{
+    _D("Create Security origin database");
+    // automatically create security origin database
+    using namespace SecurityOriginDB;
+    using namespace WrtDB;
+
+    try{
+        SecurityOriginDAO dao(m_context.locations->getPkgId());
+        // Checking privilege list for setting security origin exception data
+        FOREACH(it, m_context.widgetConfig.configInfo.privilegeList) {
+            std::map<std::string, Feature>::const_iterator result =
+                g_W3CPrivilegeTextMap.find(DPL::ToUTF8String(it->name));
+            if (result != g_W3CPrivilegeTextMap.end()) {
+                if (result->second == FEATURE_USER_MEDIA) {
+                    dao.setPrivilegeSecurityOriginData(result->second, false);
+                } else if (result->second == FEATURE_FULLSCREEN_MODE) {
+                    continue;
+                } else {
+                    dao.setPrivilegeSecurityOriginData(result->second);
+                }
+            }
+        }
+    }catch(const SecurityOriginDAO::Exception::DatabaseError& err){
+        _E("error open SecurityOrigin db %s", err.GetMessage().c_str());
+        ThrowMsg(Exceptions::UpdateFailed, "Cannot open SecurityOrigin DB");
+    }
+}
+
+void TaskDatabase::StepWidgetInterfaceDBInsert()
+{
+    _D("Create Widget Interface database");
+    using namespace WidgetInterfaceDB;
+    using namespace WrtDB;
+
+    DbWidgetHandle handle =
+        WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+
+    // backup database
+    if (m_context.isUpdateMode) {
+        std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
+        std::string backupDbPath = dbPath;
+        backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
+        _D("\"%s\" to \"%s\"", dbPath.c_str(), backupDbPath.c_str());
+        if (0 != std::rename(dbPath.c_str(), backupDbPath.c_str())) {
+            _E("widget interface database backup failed");
+            ThrowMsg(Exceptions::UpdateFailed,
+                     "widget interface database backup failed");
+        }
+    }
+
+    Try
+    {
+        // automatically create widget interface database
+        WidgetInterfaceDAO dao(handle);
+    }
+    Catch(WidgetInterfaceDAO::Exception::DatabaseError)
+    {
+        _E("widget interface database create failed");
+        ThrowMsg(Exceptions::UpdateFailed,
+                 "widget interface database create failed");
+    }
+}
+
+void TaskDatabase::StepRegisterExternalFiles()
+{
+    WrtDB::ExternalLocationList externalLocationsUpdate =
+        m_context.locations->listExternalLocations();
+    if (m_context.isUpdateMode) { //update
+        Try
+        {
+            WidgetDAOReadOnly dao(WidgetDAOReadOnly::getHandleByPkgId(m_context.widgetConfig.tzPkgid));
+            WrtDB::ExternalLocationList externalLocationsDB =
+                dao.getWidgetExternalLocations();
+            FOREACH(file, externalLocationsDB)
+            {
+                if (std::find(externalLocationsUpdate.begin(),
+                              externalLocationsUpdate.end(),
+                              *file) == externalLocationsUpdate.end())
+                {
+                    m_externalLocationsToRemove.push_back(*file);
+                }
+            }
+        }
+        Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+        {
+            _E("Given tizenId not found for update installation (Same GUID?)");
+            ThrowMsg(Exceptions::UpdateFailed,
+                     "Given tizenId not found for update installation");
+        }
+    }
+    _D("Registering external files:");
+    FOREACH(file, externalLocationsUpdate)
+    {
+        _D("  -> %s", (*file).c_str());
+    }
+
+    //set external locations to be registered
+    m_context.widgetConfig.externalLocations = externalLocationsUpdate;
+}
+
+void TaskDatabase::StepRemoveExternalFiles()
+{
+    if (!m_externalLocationsToRemove.empty()) {
+        _D("Removing external files:");
+    }
+
+    FOREACH(file, m_externalLocationsToRemove)
+    {
+        if (WrtUtilFileExists(*file)) {
+            _D("  -> %s", (*file).c_str());
+            if (-1 == remove(file->c_str())) {
+                ThrowMsg(Exceptions::RemovingFileFailure,
+                         "Failed to remove external file");
+            }
+        } else if (WrtUtilDirExists(*file)) {
+            _D("  -> %s", (*file).c_str());
+            if (!WrtUtilRemove(*file)) {
+                ThrowMsg(Exceptions::RemovingFolderFailure,
+                         "Failed to remove external directory");
+            }
+        } else {
+            _W("  -> %s(no such a path)", (*file).c_str());
+        }
+    }
+}
+
+void TaskDatabase::StepAbortDBInsert()
+{
+    _W("[DB Update Task] Aborting... (DB Clean)");
+    Try
+    {
+            WidgetDAO::unregisterWidget(m_context.widgetConfig.tzAppid);
+
+        FOREACH(iter, m_context.widgetConfig.configInfo.serviceAppInfoList) {
+            WidgetDAO::unregisterWidget(iter->serviceId);
+        }
+
+        if (m_context.isUpdateMode) {
+            FOREACH(iter, m_backAppIdList) {
+                unsigned pos = (*iter).find(L".backup");
+                TizenAppId str = (*iter).substr(0, pos);
+                WidgetDAO::updateTizenAppId(*iter, str);
+            }
+        }
+        _D("Cleaning DB successful!");
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base)
+    {
+        _E("Failed to handle StepAbortDBClean!");
+    }
+}
+
+void TaskDatabase::StepAbortAceDBInsert()
+{
+    _W("[DB Update Task] ACE DB Aborting... (DB Clean)");
+
+    FOREACH(iter, m_handleList) {
+            ace_unregister_widget(static_cast<ace_widget_handle_t>(*iter));
+    }
+
+    FOREACH(iter, m_handleToRemoveList) {
+        // Remove also old one. If it was already updated nothing wrong will happen,
+        // but if not old widget will be removed.
+        if (INVALID_WIDGET_HANDLE != *iter) {
+            ace_unregister_widget(static_cast<ace_widget_handle_t>(*iter));
+        }
+
+        if (!AceApi::registerAceWidgetFromDB(*iter))
+        {
+        _E("ace database restore failed");
+        }
+    }
+    _D("Ace data inserted");
+}
+
+void TaskDatabase::StepAbortWidgetInterfaceDBInsert()
+{
+    _D("[DB Update Task] Widget interface Aborting...");
+    using namespace WidgetInterfaceDB;
+    using namespace WrtDB;
+
+    DbWidgetHandle handle =
+        WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+    std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
+
+    // remove database
+    if (remove(dbPath.c_str()) != 0) {
+        _W("Fail to remove");
+    }
+
+    // rollback database
+    if (m_context.isUpdateMode) {
+        std::string backupDbPath = dbPath;
+        backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
+        _D("\"%s\" to \"%s\"", dbPath.c_str(), backupDbPath.c_str());
+        if (0 != std::rename(backupDbPath.c_str(), dbPath.c_str())) {
+            _W("Fail to rollback");
+        }
+    }
+}
+
+#ifdef DBOX_ENABLED
+void TaskDatabase::StepLiveboxDBInsert()
+{
+    if (m_context.widgetConfig.configInfo.m_livebox.size() <= 0) {
+        return;
+    }
+
+    std::string tizenId = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+
+    // insert specific information to web livebox db
+    for (auto it = m_context.widgetConfig.configInfo.m_livebox.begin();
+         it != m_context.widgetConfig.configInfo.m_livebox.end(); ++it)
+    {
+        std::string boxId = DPL::ToUTF8String((**it).m_liveboxId);
+        std::string boxType;
+        if ((**it).m_type.empty()) {
+            boxType = web_provider_livebox_get_default_type();
+        } else {
+            boxType = DPL::ToUTF8String((**it).m_type);
+        }
+        _D("livebox id: %s", boxId.c_str());
+        _D("livebox type: %s", boxType.c_str());
+
+        int autoLaunch = (**it).m_autoLaunch == L"true" ? 1 : 0;
+        _D("livebox auto-launch: %d", autoLaunch);
+
+        int mouseEvent = (**it).m_boxInfo.m_boxMouseEvent == L"true" ? 1 : 0;
+        _D("livebox mouse-event: %d", mouseEvent);
+
+        int pdFastOpen = (**it).m_boxInfo.m_pdFastOpen == L"true" ? 1 : 0;
+        _D("livebox pd fast-open: %d", pdFastOpen);
+
+        if (m_context.isUpdateMode) {
+            web_provider_livebox_delete_by_app_id(tizenId.c_str());
+        }
+        web_provider_livebox_insert_box_info(
+                boxId.c_str(), tizenId.c_str(), boxType.c_str(),
+                autoLaunch, mouseEvent, pdFastOpen);
+    }
+}
+#endif
+
+void TaskDatabase::StartStep()
+{
+    LOGD("--------- <TaskDatabase> : START ----------");
+}
+
+void TaskDatabase::EndStep()
+{
+    LOGD("--------- <TaskDatabase> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_database.h b/src_wearable/jobs/widget_install/task_database.h
new file mode 100755 (executable)
index 0000000..9236b1b
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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_database.h
+ * @author  Lukasz Wrzosek(l.wrzosek@samsung.com)
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task database updating
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H
+
+#include <dpl/task.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskDatabase :
+    public DPL::TaskDecl<TaskDatabase>
+{
+  private:
+    InstallerContext& m_context;
+    WrtDB::ExternalLocationList m_externalLocationsToRemove;
+
+    //TODO: temporary needed until security-server start to use pkgName instead
+    //of widget handle
+    std::list<WrtDB::DbWidgetHandle> m_handleToRemoveList;
+    std::list<WrtDB::DbWidgetHandle> m_handleList;
+    std::list<WrtDB::TizenAppId> m_backAppIdList;
+    WrtDB::TizenAppId m_orginAppId;
+
+    void StepRegisterExternalFiles();
+    void StepWrtDBInsert();
+    void StepAceDBInsert();
+    void StepSecurityOriginDBInsert();
+    void StepWidgetInterfaceDBInsert();
+    void StepRemoveExternalFiles();
+    void StepLiveboxDBInsert();
+
+    void StepAbortDBInsert();
+    void StepAbortAceDBInsert();
+    void StepAbortWidgetInterfaceDBInsert();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskDatabase(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H
diff --git a/src_wearable/jobs/widget_install/task_encrypt_resource.cpp b/src_wearable/jobs/widget_install/task_encrypt_resource.cpp
new file mode 100644 (file)
index 0000000..f048904
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * 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_ecnrypt_resource.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task encrypt resource
+ */
+#include "task_encrypt_resource.h"
+
+#undef __USE_FILE_OFFSET64
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fts.h>
+#include <string.h>
+#include <errno.h>
+#include <cstdio>
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+#include <memory>
+
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+#include <dpl/scoped_fclose.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/string.h>
+#include <ss_manager.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const std::size_t ENCRYPTION_CHUNK_MAX_SIZE = 8192; // bytes
+const std::size_t ENCRYPTION_DEC_CHUNK_SIZE = 4; // bytes
+
+std::set<std::string>& getSupportedForEncryption()
+{
+    static std::set<std::string> encryptSet;
+    if (encryptSet.empty()) {
+        encryptSet.insert(".html");
+        encryptSet.insert(".htm");
+        encryptSet.insert(".css");
+        encryptSet.insert(".js");
+    }
+    return encryptSet;
+}
+
+bool isSupportedForEncryption(const std::string &file)
+{
+    size_t foundKey = file.rfind(".");
+    if (std::string::npos != foundKey) {
+        std::string mimeType = file.substr(foundKey);
+        std::transform(mimeType.begin(), mimeType.end(), mimeType.begin(),
+                       ::tolower);
+
+        return getSupportedForEncryption().count(mimeType) > 0;
+    }
+    return false;
+}
+
+/**
+ * Opens a file.
+ *
+ * @param path Path to a file.
+ * @param mode Mode.
+ * @return Stream handle.
+ * @throw ExtractFileFailed If error (other than EINTR) occurs.
+ */
+FILE* openFile(const std::string& path, const std::string& mode)
+{
+    FILE* result = NULL;
+
+    do
+    {
+        result = fopen(path.c_str(), mode.c_str());
+    } while ((NULL == result) && (EINTR == errno));
+
+    if (NULL == result)
+    {
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::EncryptionFailed,
+                 "Could not open file " << path);
+    }
+
+    return result;
+}
+
+/**
+ * Reads bytes from a stream.
+ *
+ * @param buffer Buffer to read the bytes into.
+ * @param count Number of bytes to read.
+ * @param stream Stream to read from.
+ * @return Number of bytes read
+ * @throw ExtractFileFailed If error (other than EINTR) occurs.
+ */
+std::size_t readBytes(unsigned char* buffer, std::size_t count, FILE* stream)
+{
+    std::size_t result = std::fread(buffer,
+                                    sizeof(unsigned char),
+                                    count,
+                                    stream);
+
+    if (result != count)
+    {
+        int error = errno;
+        if (0 != std::ferror(stream))
+        {
+            if (EINTR != error)
+            {
+                ThrowMsg(Jobs::WidgetInstall::Exceptions::ErrorExternalInstallingFailure,
+                         "Error while reading data" <<
+                         " [" << DPL::GetErrnoString(error) << "]");
+            }
+        }
+    }
+
+    return result;
+}
+
+/**
+ * Writes bytes to a stream.
+ *
+ * @param buffer Data to write.
+ * @param count Number of bytes.
+ * @param stream Stream to write to.
+ * @throw ExtractFileFailed If error (other than EINTR) occurs.
+ */
+void writeBytes(unsigned char* buffer, std::size_t count, FILE* stream)
+{
+    std::size_t bytesWritten = 0;
+    std::size_t bytesToWrite = 0;
+    do
+    {
+        bytesToWrite = count - bytesWritten;
+        bytesWritten = std::fwrite(buffer + bytesWritten,
+                                   sizeof(unsigned char),
+                                   count - bytesWritten,
+                                   stream);
+        if ((bytesWritten != bytesToWrite) && (EINTR != errno))
+        {
+            int error = errno;
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::EncryptionFailed,
+                     "Error while writing data" <<
+                     " [" << DPL::GetErrnoString(error) << "]");
+        }
+    } while ((bytesWritten != bytesToWrite) && (EINTR == errno));
+}
+
+int ssmEncrypt(InstallMode::InstallTime time, std::string pkgId, const char*
+        inChunk, int inBytes, char** outChunk, int *outBytes)
+{
+    if (time == InstallMode::InstallTime::PRELOAD) {
+        return ssm_encrypt_preloaded_application(inChunk, inBytes, outChunk, outBytes);
+    } else {
+        return ssm_encrypt(pkgId.c_str(),pkgId.length(), inChunk, inBytes, outChunk, outBytes);
+    }
+}
+
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskEncryptResource::TaskEncryptResource(InstallerContext& context) :
+    DPL::TaskDecl<TaskEncryptResource>(this),
+    m_context(context)
+{
+    AddStep(&TaskEncryptResource::StartStep);
+    AddStep(&TaskEncryptResource::StepEncryptResource);
+    AddStep(&TaskEncryptResource::EndStep);
+}
+
+void TaskEncryptResource::StepEncryptResource()
+{
+    _D("Step Encrypt resource");
+
+    EncryptDirectory(m_context.locations->getSourceDir());
+}
+
+void TaskEncryptResource::EncryptDirectory(std::string path)
+{
+    FTS *fts;
+    FTSENT *ftsent;
+    char * const paths[] = { const_cast<char * const>(path.c_str()), NULL };
+
+    if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) {
+        //ERROR
+        int error = errno;
+        _W("%s: fts_open failed with error: %s", __PRETTY_FUNCTION__, strerror(error));
+        ThrowMsg(Exceptions::EncryptionFailed, "Error reading directory: "
+                 << path);
+    }
+
+    while ((ftsent = fts_read(fts)) != NULL) {
+        switch (ftsent->fts_info) {
+        case FTS_DP:
+        case FTS_DC:
+        case FTS_D:
+        case FTS_DEFAULT:
+        case FTS_SLNONE:
+            //directories, non-regular files, dangling symbolic links
+            break;
+        case FTS_F:
+        case FTS_NSOK:
+        case FTS_SL:
+            //regular files and other objects that can be counted
+            if (isSupportedForEncryption(ftsent->fts_path)) {
+                EncryptFile(ftsent->fts_path);
+            }
+            break;
+        case FTS_NS:
+        case FTS_DOT:
+        case FTS_DNR:
+        case FTS_ERR:
+        default:
+            _W("%s: traversal failed on file: %s with error: %s", __PRETTY_FUNCTION__, ftsent->fts_path, strerror(ftsent->fts_errno));
+            ThrowMsg(Exceptions::EncryptionFailed, "Error reading file");
+            break;
+        }
+    }
+
+    if (fts_close(fts) == -1) {
+        int error = errno;
+        _W("%s: fts_close failed with error: %s", __PRETTY_FUNCTION__, strerror(error));
+    }
+}
+
+void TaskEncryptResource::EncryptFile(const std::string &fileName)
+{
+    _D("Encrypt file: %s", fileName.c_str());
+    std::string encFile = fileName + ".enc";
+
+    struct stat info;
+    memset(&info, 0, sizeof(info));
+    if (stat(fileName.c_str(), &info) != 0)
+    {
+        int error = errno;
+        ThrowMsg(Exceptions::EncryptionFailed,
+                "Could not access file " << fileName <<
+                "[" << DPL::GetErrnoString(error) << "]");
+    }
+    const std::size_t fileSize = info.st_size;
+    if (0 == fileSize) {
+        _D("%s size is 0, so encryption is skiped", fileName.c_str());
+        return;
+    }
+
+    // If update installed preload web, should skip encryption.
+    if (!(m_context.mode.rootPath == InstallMode::RootPath::RO &&
+                (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                 || m_context.mode.installTime == InstallMode::InstallTime::FOTA)
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+
+        DPL::ScopedFClose inFile(openFile(fileName, "r"));
+        DPL::ScopedFClose outFile(openFile(encFile, "w"));
+
+        const std::size_t chunkSize = (fileSize > ENCRYPTION_CHUNK_MAX_SIZE
+                ? ENCRYPTION_CHUNK_MAX_SIZE : fileSize);
+
+        std::unique_ptr<unsigned char[]> inChunk(new unsigned char[chunkSize]);
+        std::size_t bytesRead = 0;
+        std::string pkgId = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+
+        do
+        {
+            bytesRead = readBytes(inChunk.get(), chunkSize, inFile.Get());
+            if (0 != bytesRead) {
+                int outDecSize = 0;
+                char *outChunk = NULL;
+                if (0 != ssmEncrypt(m_context.mode.installTime, pkgId,
+                            (char*)inChunk.get(), (int)bytesRead,
+                            &outChunk, &outDecSize)) {
+                    ThrowMsg(Exceptions::EncryptionFailed,
+                            "Encryption Failed using TrustZone");
+                }
+
+                std::stringstream toString;
+                toString << outDecSize;
+
+                writeBytes((unsigned char*)toString.str().c_str(),
+                        sizeof(int), outFile.Get());
+                writeBytes((unsigned char*)outChunk, outDecSize, outFile.Get());
+                delete outChunk;
+            }
+            inChunk.reset(new unsigned char[chunkSize]);
+
+        } while (0 == std::feof(inFile.Get()));
+
+        outFile.Reset();
+        inFile.Reset();
+
+        _D("File encrypted successfully");
+        _D("Remove plain-text file: %s", fileName.c_str());
+        if (0 != unlink(fileName.c_str()))
+        {
+            Throw(Exceptions::EncryptionFailed);
+        }
+
+        _D("Rename encrypted file");
+        if (0 != std::rename(encFile.c_str(), fileName.c_str()))
+        {
+            Throw(Exceptions::EncryptionFailed);
+        }
+    }
+
+    WrtDB::EncryptedFileInfo fileInfo;
+    fileInfo.fileName = DPL::FromUTF8String(fileName);
+    fileInfo.fileSize = fileSize;
+
+    m_context.widgetConfig.encryptedFiles.insert(fileInfo);
+}
+
+void TaskEncryptResource::StartStep()
+{
+    LOGD("--------- <TaskEncryptResource> : START ----------");
+}
+
+void TaskEncryptResource::EndStep()
+{
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_ECRYPTION_FILES,
+            "Ecrypt resource files");
+
+    LOGD("--------- <TaskEncryptResource> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_encrypt_resource.h b/src_wearable/jobs/widget_install/task_encrypt_resource.h
new file mode 100644 (file)
index 0000000..b89a992
--- /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_encrypt_resource.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_RESOURCE_ENCRYPT_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_RESOURCE_ENCRYPT_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskEncryptResource : public DPL::TaskDecl<TaskEncryptResource>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+    std::string tempInstalledPath;
+
+    void StepEncryptResource();
+
+    void StartStep();
+    void EndStep();
+
+    void EncryptDirectory(std::string path);
+    void EncryptFile(const std::string &fileName);
+
+  public:
+    explicit TaskEncryptResource(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_ENCRYPT_RESOURCE_H_ */
diff --git a/src_wearable/jobs/widget_install/task_file_manipulation.cpp b/src_wearable/jobs/widget_install/task_file_manipulation.cpp
new file mode 100644 (file)
index 0000000..ae1128e
--- /dev/null
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2010 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 <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <string>
+#include <fstream>
+#include <vconf.h>
+
+#include <widget_install/task_file_manipulation.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/directory_api.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <dpl/foreach.h>
+#include <dpl/assert.h>
+#include <dpl/errno_string.h>
+#include <dpl/utils/folder_size.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <widget_install_to_external.h>
+#include <installer_log.h>
+#include <widget_unzip.h>
+
+#define WEBAPP_DEFAULT_UID  5000
+#define WEBAPP_DEFAULT_GID  5000
+
+namespace {
+const mode_t PRIVATE_STORAGE_MODE = 0700;
+const mode_t SHARED_STORAGE_MODE = 0755;
+}
+
+using namespace WrtDB;
+
+namespace {
+const char* GLIST_RES_DIR = "res";
+
+bool _FolderCopy(std::string source, std::string dest)
+{
+    DIR* dir = opendir(source.c_str());
+    if (NULL == dir) {
+        return false;
+    }
+
+    struct dirent dEntry;
+    struct dirent *dEntryResult;
+    int return_code;
+
+    do {
+        struct stat statInfo;
+        return_code = readdir_r(dir, &dEntry, &dEntryResult);
+        if (dEntryResult != NULL && return_code == 0) {
+            std::string fileName = dEntry.d_name;
+            std::string fullName = source + "/" + fileName;
+
+            if (stat(fullName.c_str(), &statInfo) != 0) {
+                closedir(dir);
+                return false;
+            }
+
+            if (S_ISDIR(statInfo.st_mode)) {
+                if (("." == fileName) || (".." == fileName)) {
+                    continue;
+                }
+                std::string destFolder = dest + "/" + fileName;
+                WrtUtilMakeDir(destFolder);
+
+                if (!_FolderCopy(fullName, destFolder)) {
+                    closedir(dir);
+                    return false;
+                }
+            }
+
+            std::string destFile = dest + "/" + fileName;
+            std::ifstream infile(fullName);
+            std::ofstream outfile(destFile);
+            outfile << infile.rdbuf();
+            outfile.close();
+            infile.close();
+        }
+    } while (dEntryResult != NULL && return_code == 0);
+    closedir(dir);
+    return true;
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
+    DPL::TaskDecl<TaskFileManipulation>(this),
+    m_context(context),
+    m_extHandle(NULL)
+{
+    AddStep(&TaskFileManipulation::StartStep);
+    AddStep(&TaskFileManipulation::StepCheckInstallLocation);
+    AddStep(&TaskFileManipulation::StepPrepareRootDirectory);
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
+    {
+        AddStep(&TaskFileManipulation::StepUnzipWgtFile);
+    }
+    AddStep(&TaskFileManipulation::EndStep);
+
+    AddAbortStep(&TaskFileManipulation::StepAbortPrepareRootDirectory);
+}
+
+void TaskFileManipulation::StepCheckInstallLocation()
+{
+    _D("StepCheckInstallLocation");
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+        return;
+    }
+
+    // If webapp is hybrid app, it should be installed to internal storage.
+    // Because Service app should be installed to internal.
+    if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
+        m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+        return;
+    }
+
+    std::string installedPath = WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    WidgetUnzip wgtUnzip(m_context.requestedPath);
+
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_AUTO) {
+        int storage = 0;
+        // vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT)
+        // 0 : phone internal memory
+        // 1 : SD card
+        if (vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
+                    &storage)) {
+            _E("vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT) \
+                    failed.");
+        }
+        _D("default setting : storage [%d]", storage);
+        if (storage) {
+            m_context.locationType = INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
+        } else {
+            m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+            if(!wgtUnzip.checkAvailableSpace(installedPath)) {
+                m_context.locationType = INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
+            }
+        }
+    }
+
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
+        int mmcStatus;
+        if (vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmcStatus)) {
+            _E("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
+            mmcStatus = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
+        }
+
+        if (VCONFKEY_SYSMAN_MMC_MOUNTED != mmcStatus) {
+            _D("mmcStatus is MMC_REMOVED or NOT_MOUNTED.");
+            m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
+        }
+    }
+
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_INTERNAL_ONLY) {
+        if(!wgtUnzip.checkAvailableSpace(installedPath)) {
+            ThrowMsg(Exceptions::OutOfStorageFailed, "There is no space for installation");
+        }
+    }
+}
+
+void TaskFileManipulation::StepPrepareRootDirectory()
+{
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
+        prepareExternalDir();
+    } else {
+        std::string widgetPath = m_context.locations->getPackageInstallationDir();
+        std::string widgetBinPath = m_context.locations->getBinaryDir();
+        std::string widgetSrcPath = m_context.locations->getSourceDir();
+
+        if (!m_context.isUpdateMode) {
+            _D("Remove existing directory : %s", widgetPath.c_str());
+            DPL::Utils::TryRemove(DPL::Utils::Path(widgetPath));
+        }
+        WrtUtilMakeDir(widgetPath);
+
+        _D("Create resource directory");
+        WrtUtilMakeDir(widgetBinPath);
+        WrtUtilMakeDir(widgetSrcPath);
+    }
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_DIR_CREATE,
+        "Widget Directory Created");
+}
+
+void TaskFileManipulation::StepUnzipWgtFile()
+{
+    if (m_context.widgetConfig.packagingType != PKG_TYPE_HOSTED_WEB_APP) {
+        std::string instDir;
+        if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
+            instDir = m_context.locations->getPackageInstallationDir();
+        } else {
+            instDir = m_context.locations->getSourceDir();
+        }
+
+        _D("unzip file to %s", instDir.c_str());
+
+        WidgetUnzip wgtUnzip(m_context.requestedPath);
+        wgtUnzip.unzipWgtFile(instDir);
+    } else {
+        _D("From browser installation - unzip is not done");
+    }
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_UNZIP_WGT,
+        "Unzip Wgt file");
+}
+
+void TaskFileManipulation::StepAbortPrepareRootDirectory()
+{
+    _D("[Create Root Directory]  Aborting.... (Rename path)");
+    if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
+        if (m_context.isUpdateMode) {
+            WidgetInstallToExtSingleton::Instance().postUpgrade(false);
+        } else {
+            WidgetInstallToExtSingleton::Instance().postInstallation(false);
+        }
+        WidgetInstallToExtSingleton::Instance().deinitialize();
+    } else {
+        std::string widgetPath;
+        widgetPath = m_context.locations->getPackageInstallationDir();
+        if (!WrtUtilRemove(widgetPath)) {
+            _E("Error occurs during removing existing folder");
+        }
+        // Remove user data directory if preload web app.
+        std::string userData = m_context.locations->getUserDataRootDir();
+        if (0 == access(userData.c_str(), F_OK)) {
+            if (!WrtUtilRemove(userData)) {
+                _E("Error occurs during removing user data directory");
+            }
+        }
+    }
+}
+
+void TaskFileManipulation::prepareExternalDir()
+{
+    _D("Step prepare to install in exernal directory");
+    Try {
+        std::string pkgid =
+            DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+
+        WidgetInstallToExtSingleton::Instance().initialize(pkgid);
+
+        std::unique_ptr<DPL::ZipInput> zipFile(new
+                DPL::ZipInput(m_context.requestedPath));
+        double unzipSize = zipFile->GetTotalUncompressedSize();
+        int folderSize = (int)(unzipSize / (1024 * 1024)) + 1;
+
+        GList *list = NULL;
+        app2ext_dir_details* dirDetail = NULL;
+
+        dirDetail = (app2ext_dir_details*) calloc(1,
+                sizeof(
+                    app2ext_dir_details));
+        if (NULL == dirDetail) {
+            ThrowMsg(Exceptions::ErrorExternalInstallingFailure,
+                    "error in app2ext");
+        }
+        dirDetail->name = strdup(GLIST_RES_DIR);
+        dirDetail->type = APP2EXT_DIR_RO;
+        list = g_list_append(list, dirDetail);
+
+        if (m_context.isUpdateMode) {
+            WidgetInstallToExtSingleton::Instance().preUpgrade(list,
+                                                               folderSize);
+        } else {
+            WidgetInstallToExtSingleton::Instance().preInstallation(list,
+                                                                    folderSize);
+        }
+        free(dirDetail);
+        g_list_free(list);
+
+        /* make bin directory */
+        std::string widgetBinPath = m_context.locations->getBinaryDir();
+        WrtUtilMakeDir(widgetBinPath);
+        std::string sourceDir = m_context.locations->getSourceDir();
+        WrtUtilMakeDir(sourceDir);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed) {
+        ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
+                   "Error during \
+                create external folder ");
+    }
+    Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
+    {
+        ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
+                   "Error during create external folder ");
+    }
+}
+
+void TaskFileManipulation::StartStep()
+{
+    LOGD("--------- <TaskFileManipulation> : START ----------");
+}
+
+void TaskFileManipulation::EndStep()
+{
+    LOGD("--------- <TaskFileManipulation> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_file_manipulation.h b/src_wearable/jobs/widget_install/task_file_manipulation.h
new file mode 100644 (file)
index 0000000..113ca72
--- /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    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_FILE_MANIPULATION_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_FILE_MANIPULATION_UPDATE_H
+
+#include <dpl/task.h>
+#include <app2ext_interface.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskFileManipulation :
+    public DPL::TaskDecl<TaskFileManipulation>
+{
+    InstallerContext& m_context;
+    app2ext_handle *m_extHandle;
+
+    // install internal location
+    void StepCheckInstallLocation();
+    void StepPrepareRootDirectory();
+    void StepUnzipWgtFile();
+    void StepAbortPrepareRootDirectory();
+    void StepLinkForPreload();
+    void StartStep();
+    void EndStep();
+
+    // install external location
+    void prepareExternalDir();
+
+  public:
+    TaskFileManipulation(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_FILE_MANIPULATION_H
diff --git a/src_wearable/jobs/widget_install/task_install_ospsvc.cpp b/src_wearable/jobs/widget_install/task_install_ospsvc.cpp
new file mode 100644 (file)
index 0000000..4016a6f
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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_install_ospsvc.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task  install osp service
+ */
+#include "task_install_ospsvc.h"
+
+#include <unistd.h>
+#include <string>
+
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <fstream>
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/utils/bash_utils.h>
+#include <privilege-control.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+const char* OSP_INSTALL_STR1 = "/usr/etc/package-manager/backend/tpk -iv ";
+const char* OSP_INSTALL_STR2 = " -p ";
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskInstallOspsvc::TaskInstallOspsvc(InstallerContext& context) :
+    DPL::TaskDecl<TaskInstallOspsvc>(this),
+    m_context(context)
+{
+    AddStep(&TaskInstallOspsvc::StartStep);
+    AddStep(&TaskInstallOspsvc::StepUninstallSmack);
+    AddStep(&TaskInstallOspsvc::StepInstallOspService);
+    AddStep(&TaskInstallOspsvc::EndStep);
+}
+
+void TaskInstallOspsvc::StepUninstallSmack()
+{
+    std::string pkgId = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+    if (m_context.isUpdateMode) {
+        _D("StepUninstallSmack");
+        if (PC_OPERATION_SUCCESS != perm_app_uninstall(pkgId.c_str())) {
+            _E("failure in removing smack rules file");
+            ThrowMsg(Exceptions::NotAllowed, "Update failure. "
+                    "failure in delete smack rules file before update.");
+        }
+    }
+}
+
+void TaskInstallOspsvc::StepInstallOspService()
+{
+    _D("Step: installation for osp service");
+
+    std::ostringstream commStr;
+    commStr << OSP_INSTALL_STR1<< BashUtils::escape_arg(
+        m_context.locations->getPackageInstallationDir())
+        << OSP_INSTALL_STR2 << m_context.certLevel;
+    _D("osp install command : %s", commStr.str().c_str());
+
+    char readBuf[MAX_BUF_SIZE];
+    FILE *fd;
+    fd = popen(commStr.str().c_str(), "r");
+    if (NULL == fd) {
+        _E("Failed to installtion osp service");
+        ThrowMsg(Exceptions::InstallOspsvcFailed,
+                 "Error occurs during\
+                install osp service");
+    }
+
+    if (fgets(readBuf, MAX_BUF_SIZE, fd) == NULL)
+    {
+        _E("Failed to installtion osp service.\
+                Inability of reading file.");
+        ThrowMsg(Exceptions::InstallOspsvcFailed,
+                "Error occurs during\
+                install osp service");
+    }
+    _D("return value : %s", readBuf);
+
+    int result = atoi(readBuf);
+    if (0 != result) {
+        ThrowMsg(Exceptions::InstallOspsvcFailed,
+                 "Error occurs during\
+                install osp service");
+    }
+
+    pclose(fd);
+}
+
+void TaskInstallOspsvc::StartStep()
+{
+    LOGD("--------- <TaskInstallOspsvc> : START ----------");
+}
+
+void TaskInstallOspsvc::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_INSTALL_OSPSVC,
+        "Installed Osp servcie");
+
+    LOGD("--------- <TaskInstallOspsvc> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_install_ospsvc.h b/src_wearable/jobs/widget_install/task_install_ospsvc.h
new file mode 100644 (file)
index 0000000..6648d73
--- /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_install_ospsvc.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_INSTALL_OSPSVC_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_INSTALL_OSPSVC_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskInstallOspsvc : public DPL::TaskDecl<TaskInstallOspsvc>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+
+    void StepInstallOspService();
+    void StepUninstallSmack();
+
+    void StepAbortInstall();
+
+    void StartStep();
+    void EndStep();
+
+    // return callback
+    static int StatusCallback(
+        int req_id, const char *pkg_type, const char *pkg_name,
+        const char *key, const char *val, const void *pmsg,
+        void *priv_data);
+
+  public:
+    explicit TaskInstallOspsvc(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_INSTALL_OSPSVC_H_ */
diff --git a/src_wearable/jobs/widget_install/task_manifest_file.cpp b/src_wearable/jobs/widget_install/task_manifest_file.cpp
new file mode 100755 (executable)
index 0000000..ac897fa
--- /dev/null
@@ -0,0 +1,1614 @@
+/*
+ * 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_manifest_file.cpp
+ * @author  Pawel Sikorski (p.sikorski@samgsung.com)
+ * @version
+ * @brief
+ */
+
+//SYSTEM INCLUDES
+#include <unistd.h>
+#include <string>
+#include <dpl/assert.h>
+#include <dirent.h>
+#include <fstream>
+#include <ail.h>
+
+//WRT INCLUDES
+#include <widget_install/task_manifest_file.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#ifdef DBOX_ENABLED
+#include <web_provider_livebox_info.h>
+#include <web_provider_plugin_info.h>
+#endif
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/file_input.h>
+#include <dpl/errno_string.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/utils/wrt_utility.h>
+#include <map>
+#include <libxml_utils.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <dpl/localization/LanguageTagsProvider.h>
+#include <dpl/utils/path.h>
+
+#include <installer_log.h>
+
+#define DEFAULT_ICON_NAME   "icon.png"
+#define DEFAULT_PREVIEW_NAME   "preview.png"
+
+using namespace WrtDB;
+
+namespace {
+typedef std::map<DPL::String, DPL::String> LanguageTagMap;
+
+const char* const STR_TRUE = "true";
+const char* const STR_FALSE = "false";
+const char* const STR_NODISPLAY = "nodisplay";
+const char* const STR_CATEGORY_WATCH_CLOCK = "com.samsung.wmanager.WATCH_CLOCK";
+const char* const STR_CATEGORY_WATCH_APP = "com.samsung.wmanager.WATCH_APP";
+
+#ifdef IME_ENABLED
+const char* const STR_CATEGORY_IME = "http://tizen.org/category/ime";
+#endif
+
+#ifdef SERVICE_ENABLED
+const char* const STR_CATEGORY_SERVICE = "http://tizen.org/category/service";
+#endif
+
+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;
+
+    _D("Trying to map language tag: %ls", langTag.c_str());
+    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;
+        _D("Mapping IANA Language tag to language tag: %ls -> %ls", langTag.c_str(), (*ret).c_str());
+    }
+
+    return ret;
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+const char * TaskManifestFile::encoding = "UTF-8";
+
+TaskManifestFile::TaskManifestFile(InstallerContext &inCont) :
+    DPL::TaskDecl<TaskManifestFile>(this),
+    m_context(inCont),
+    writer(NULL)
+{
+    if (InstallMode::Command::RECOVERY == m_context.mode.command) {
+        AddStep(&TaskManifestFile::stepGenerateManifest);
+    } else {
+        AddStep(&TaskManifestFile::stepCopyIconFiles);
+#ifdef DBOX_ENABLED
+        AddStep(&TaskManifestFile::stepCopyLiveboxFiles);
+#endif
+#ifdef SERVICE_ENABLED
+        AddStep(&TaskManifestFile::stepCopyServiceIconFiles);
+#endif
+        AddStep(&TaskManifestFile::stepCopyAccountIconFiles);
+        AddStep(&TaskManifestFile::stepCreateExecFile);
+        AddStep(&TaskManifestFile::stepCreateLinkNPPluginsFile);
+        AddStep(&TaskManifestFile::stepGenerateManifest);
+    }
+}
+
+TaskManifestFile::~TaskManifestFile()
+{}
+
+void TaskManifestFile::stepCreateExecFile()
+{
+    std::string exec = m_context.locations->getExecFile();
+    std::string clientExeStr = GlobalConfig::GetWrtClientExec();
+
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //default widget
+    std::stringstream postfix;
+    postfix << AppControlPrefix::PROCESS_PREFIX << 0;
+    std::string controlExec = exec;
+    controlExec.append(postfix.str());
+
+    errno = 0;
+    if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0)
+    {
+        int error = errno;
+        if (error)
+            _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+    }
+
+    // app-control widgets
+    unsigned int indexMax = 0;
+    FOREACH(it, m_context.widgetConfig.configInfo.appControlList) {
+        if (it->m_index > indexMax) {
+            indexMax = it->m_index;
+        }
+    }
+
+    for (std::size_t i = 1; i <= indexMax; ++i) {
+        std::stringstream postfix;
+        postfix << AppControlPrefix::PROCESS_PREFIX << i;
+        std::string controlExec = exec;
+        controlExec.append(postfix.str());
+        errno = 0;
+        if (symlink(clientExeStr.c_str(), controlExec.c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+            }
+        }
+    }
+#else
+    //default widget
+    _D("link -s %s %s", clientExeStr.c_str(), exec.c_str());
+    errno = 0;
+    if (symlink(clientExeStr.c_str(), exec.c_str()) != 0)
+    {
+        int error = errno;
+        if (error)
+            _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+    }
+#ifdef SERVICE_ENABLED
+    std::string serviceExeStr = GlobalConfig::GetWrtServiceExec();
+
+    FOREACH(it, m_context.widgetConfig.configInfo.serviceAppInfoList) {
+        std::string serviceExec = m_context.locations->getBinaryDir() + "/" + DPL::ToUTF8String(it->serviceId);
+        errno = 0;
+        _D("link -s %s %s", serviceExeStr.c_str(), serviceExec.c_str());
+        if (symlink(serviceExeStr.c_str(), serviceExec.c_str()) != 0)
+        {
+            int error = errno;
+            if (error)
+                _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+        }
+    }
+#endif
+#endif
+    // creation of box symlink
+    ConfigParserData::LiveboxList& liveboxList =
+        m_context.widgetConfig.configInfo.m_livebox;
+    if (!liveboxList.empty()) {
+        std::string boxExec = "/usr/bin/WebProcess";
+        std::string boxSymlink = m_context.locations->getExecFile();
+        boxSymlink += ".d-box";
+
+        errno = 0;
+        if (symlink(boxExec.c_str(), boxSymlink.c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                _E("Failed to make a symbolic name for a file [%s]", DPL::GetErrnoString(error).c_str());
+            }
+        }
+    }
+
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_CREATE_EXECFILE,
+            "Widget execfile creation Finished");
+}
+
+void TaskManifestFile::stepCreateLinkNPPluginsFile()
+{
+    _D("stepCreateLinkNPPluginsFile");
+    if (0 == access(m_context.locations->getNPPluginsDir().c_str(), F_OK)) {
+        _D("This webapp has NPPlugins");
+        std::string pluginsExec = "/usr/bin/PluginProcess";
+        errno = 0;
+        if (symlink(pluginsExec.c_str(),
+                    m_context.locations->getNPPluginsExecFile().c_str()) != 0) {
+            int error = errno;
+            if (error) {
+                _E("Failed to create symbolic link for npplugins : %ls",
+                        DPL::GetErrnoString(error).c_str());
+            }
+        }
+    }
+}
+
+void TaskManifestFile::stepCopyIconFiles()
+{
+    _D("CopyIconFiles");
+
+    //This function copies icon to desktop icon path. For each locale avaliable
+    //which there is at least one icon in widget for, icon file is copied.
+    //Coping prioritize last positions when coping. If there is several icons
+    //with given locale, the one, that will be copied, will be icon
+    //which is declared by <icon> tag later than the others in config.xml of
+    // widget
+
+    std::vector<Locale> generatedLocales;
+
+    WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
+        m_context.widgetConfig.localizationData.icons;
+
+    for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_iterator
+         icon = icons.begin();
+         icon != icons.end();
+         ++icon)
+    {
+        DPL::String src = icon->src;
+        FOREACH(locale, icon->availableLocales)
+        {
+            DPL::String tmp = (icon->isSmall ? L"small_" : L"") + (*locale);
+            _D("Icon for locale: %ls is: %ls", tmp.c_str(), src.c_str());
+
+            if (std::find(generatedLocales.begin(), generatedLocales.end(),
+                    tmp) != generatedLocales.end())
+            {
+                _D("Skipping - has that locale");
+                continue;
+            } else {
+                generatedLocales.push_back(tmp);
+            }
+
+            DPL::Utils::Path sourceFile(m_context.locations->getSourceDir());
+            if (!locale->empty()) {
+                sourceFile /= "locales";
+                sourceFile /= *locale;
+            }
+            sourceFile /= src;
+
+            DPL::Utils::Path
+                targetFile(m_context.locations->getSharedResourceDir());
+            targetFile /= (icon->isSmall ? L"small_" : L"")
+                        + getIconTargetFilename(*locale, sourceFile.Extension());
+
+            if (m_context.widgetConfig.packagingType ==
+                WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+            {
+                m_context.locations->setIconTargetFilenameForLocale(
+                    targetFile.Fullpath());
+            }
+
+            _D("Copying icon: %s -> %s", sourceFile.Filename().c_str(), targetFile.Filename().c_str());
+
+            icon_list.push_back(targetFile.Fullpath());
+
+            Try
+            {
+                DPL::FileInput input(sourceFile.Fullpath());
+                DPL::FileOutput output(targetFile.Fullpath());
+                DPL::Copy(&input, &output);
+            }
+
+            Catch(DPL::FileInput::Exception::Base)
+            {
+                // Error while opening or closing source file
+                //ReThrowMsg(InstallerException::CopyIconFailed,
+                // sourceFile.str());
+                _E("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());
+                _E("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());
+                _E("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");
+}
+
+#ifdef SERVICE_ENABLED
+void TaskManifestFile::stepCopyServiceIconFiles()
+{
+    _D("Copy Service icon files");
+
+    WrtDB::ConfigParserData::ServiceAppInfoList service = m_context.widgetConfig.configInfo.serviceAppInfoList;
+
+    if (service.size() <= 0) {
+        return;
+    }
+
+    FOREACH(it, service)
+    {
+        if (it->m_iconsList.empty()) {
+            _D("Widget doesn't contain Service icon");
+            return;
+        }
+
+        ConfigParserData::IconsList iconsList = it->m_iconsList;
+        FOREACH(iconIt, iconsList) {
+            std::string sourceFile = m_context.locations->getSourceDir() +
+                                     '/' +
+                                     DPL::ToUTF8String(iconIt->src);
+            std::string targetFile = m_context.locations->getSharedResourceDir() +
+                                     '/' +
+                                     DPL::ToUTF8String(it->serviceId) +
+                                     ".png";
+            copyFile(sourceFile, targetFile);
+        }
+    }
+}
+#endif
+
+#ifdef DBOX_ENABLED
+void TaskManifestFile::stepCopyLiveboxFiles()
+{
+    _D("Copy Livebox Files");
+
+    using namespace WrtDB;
+    ConfigParserData &data = m_context.widgetConfig.configInfo;
+    ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
+
+    if (liveBoxList.size() <= 0) {
+        return;
+    }
+
+    std::ostringstream sourceFile;
+    std::ostringstream targetFile;
+
+    FOREACH (boxIt, liveBoxList) {
+        ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+            (**boxIt).m_boxInfo.m_boxSize;
+        FOREACH (sizeIt, boxSizeList) {
+            std::string preview = DPL::ToUTF8String((*sizeIt).m_preview);
+            if (preview.empty()) {
+                continue;
+            }
+            sourceFile << m_context.locations->getSourceDir() << "/";
+            sourceFile << preview;
+            targetFile << m_context.locations->getSharedDataDir() << "/";
+            targetFile << (**boxIt).m_liveboxId << ".";
+            targetFile << DPL::ToUTF8String((*sizeIt).m_size) << "." << DEFAULT_PREVIEW_NAME;
+
+            copyFile(sourceFile.str(), targetFile.str());
+
+            // clear stream objects
+            sourceFile.str("");
+            targetFile.str("");
+        }
+        // check this livebox has icon element
+        std::string icon = DPL::ToUTF8String((**boxIt).m_icon);
+        if (icon.empty()) {
+            continue;
+        }
+        sourceFile << m_context.locations->getSourceDir() << "/";
+        sourceFile << icon;
+        targetFile << m_context.locations->getSharedDataDir() << "/";
+        targetFile << (**boxIt).m_liveboxId << "." << DEFAULT_ICON_NAME;
+
+        copyFile(sourceFile.str(), targetFile.str());
+
+        // clear stream objects
+        sourceFile.str("");
+        targetFile.str("");
+    }
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_COPY_LIVEBOX_FILES,
+        "Livebox files copy Finished");
+}
+#endif
+
+void TaskManifestFile::stepCopyAccountIconFiles()
+{
+    _D("Copy Account icon files");
+    WrtDB::ConfigParserData::AccountProvider account =
+        m_context.widgetConfig.configInfo.accountProvider;
+
+    if (account.m_iconSet.empty()) {
+        _D("Widget doesn't contain Account");
+        return;
+    }
+
+    FOREACH(it, account.m_iconSet) {
+        std::string sourceFile = m_context.locations->getSourceDir() +
+                                 '/' +
+                                 DPL::ToUTF8String(it->second);
+        std::string targetFile = m_context.locations->getSharedResourceDir() +
+                                 '/' +
+                                 DPL::ToUTF8String(it->second);
+        copyFile(sourceFile, targetFile);
+    }
+}
+
+void TaskManifestFile::copyFile(const std::string& sourceFile,
+                                const std::string& targetFile)
+{
+    Try
+    {
+        DPL::FileInput input(sourceFile);
+        DPL::FileOutput output(targetFile);
+        DPL::Copy(&input, &output);
+    }
+    Catch(DPL::Exception)
+    {
+        _E("Failed to file copy. %s to %s", sourceFile.c_str(), targetFile.c_str());
+        ReThrowMsg(Exceptions::CopyIconFailed, "Error during file copy.");
+    }
+}
+
+#ifdef DBOX_ENABLED
+bool TaskManifestFile::addBoxUiApplication(Manifest& manifest)
+{
+    UiApplication uiApp;
+    std::string postfix = ".d-box";
+    static bool isAdded = false;
+
+    Try
+    {
+        if (isAdded) {
+            _D("UiApplication for d-box is already added");
+            return false;
+        }
+        uiApp.setNodisplay(true);
+        uiApp.setTaskmanage(false);
+        uiApp.setMultiple(false);
+        setWidgetName(manifest, uiApp);
+        setWidgetIcons(uiApp);
+
+        // appid for box is like [webapp id].d-box
+        setWidgetIds(manifest, uiApp, postfix);
+        // executable path for box is like [app path]/bin/[webapp id].d-box
+        setWidgetExecPath(uiApp, postfix);
+        manifest.addUiApplication(uiApp);
+        isAdded = true;
+
+        return true;
+    }
+    Catch(DPL::Exception)
+    {
+        _E("Adding UiApplication on xml is failed.");
+        isAdded = false;
+        return false;
+    }
+}
+#endif
+
+DPL::String TaskManifestFile::getIconTargetFilename(
+    const DPL::String& languageTag, const std::string & ext) const
+{
+    DPL::OStringStream filename;
+    TizenAppId appid = m_context.widgetConfig.tzAppid;
+
+    filename << DPL::ToUTF8String(appid).c_str();
+
+    if (!languageTag.empty()) {
+        DPL::OptionalString tag = getLangTag(languageTag); // translate en ->
+                                                           // en_US etc
+        if (!tag) {
+            tag = languageTag;
+        }
+        DPL::String locale =
+            LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+
+        if (locale.empty()) {
+            filename << L"." << languageTag;
+        } else {
+            filename << L"." << locale;
+        }
+    }
+
+    if(!ext.empty())
+    {
+        filename << L"." + DPL::FromUTF8String(ext);
+    }
+    return filename.str();
+}
+
+void TaskManifestFile::saveLocalizedKey(std::ofstream &file,
+                                        const DPL::String& key,
+                                        const DPL::String& languageTag)
+{
+    DPL::String locale =
+        LanguageTagsProvider::BCP47LanguageTagToLocale(languageTag);
+
+    file << key;
+    if (!locale.empty()) {
+        file << "[" << locale << "]";
+    }
+    file << "=";
+}
+
+void TaskManifestFile::stepGenerateManifest()
+{
+    TizenPkgId pkgid = m_context.widgetConfig.tzPkgid;
+    manifest_name = pkgid + L".xml";
+
+    // In FOTA environment, Use temporary directory created by pkgmgr.
+    // Becuase /tmp can be read-only filesystem.
+    if (m_context.mode.installTime == InstallMode::InstallTime::FOTA) {
+        manifest_file += L"/opt/share/packages/.recovery/wgt/" + manifest_name;
+    } else {
+        manifest_file += L"/tmp/" + manifest_name;
+    }
+
+    //libxml - init and check
+    LibxmlSingleton::Instance().init();
+
+    writeManifest(manifest_file);
+
+    std::ostringstream destFile;
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        destFile << WrtDB::GlobalConfig::GetPreloadManifestPath() << "/";
+    } else {
+        destFile << WrtDB::GlobalConfig::GetManifestPath() << "/";
+    }
+
+    destFile << DPL::ToUTF8String(manifest_name);
+    commit_manifest = destFile.str();
+    _D("Commiting manifest file : %s", commit_manifest.c_str());
+
+    commitManifest();
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_CREATE_MANIFEST,
+        "Widget Manifest Creation Finished");
+}
+
+void TaskManifestFile::commitManifest()
+{
+
+    if (!(m_context.mode.rootPath == InstallMode::RootPath::RO &&
+                (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                 || m_context.mode.installTime == InstallMode::InstallTime::FOTA)
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+        _D("cp %ls %s", manifest_file.c_str(), commit_manifest.c_str());
+
+        DPL::FileInput input(DPL::ToUTF8String(manifest_file));
+        DPL::FileOutput output(commit_manifest);
+        DPL::Copy(&input, &output);
+        _D("Manifest writen to: %s", commit_manifest.c_str());
+
+        //removing temp file
+        unlink((DPL::ToUTF8String(manifest_file)).c_str());
+        manifest_file = DPL::FromUTF8String(commit_manifest);
+    }
+}
+
+void TaskManifestFile::writeManifest(const DPL::String & path)
+{
+    _D("Generating manifest file : %ls", path.c_str());
+    Manifest manifest;
+    UiApplication uiApp;
+
+#ifdef MULTIPROCESS_SERVICE_SUPPORT
+    //default widget content
+    std::stringstream postfix;
+    // index 0 is reserved
+    postfix << AppControlPrefix::PROCESS_PREFIX << 0;
+    setWidgetExecPath(uiApp, postfix.str());
+    setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
+    setWidgetIcons(uiApp);
+    setWidgetDescription(manifest);
+    setWidgetManifest(manifest);
+    setWidgetOtherInfo(uiApp);
+    setAppCategory(uiApp);
+    setMetadata(uiApp);
+    // move to the last of this procedure
+    //setLiveBoxInfo(manifest);
+    setAccount(manifest);
+    setPrivilege(manifest);
+    manifest.addUiApplication(uiApp);
+
+    //app-control content
+    ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+    FOREACH(it, appControlList) {
+        UiApplication uiApp;
+
+        uiApp.setTaskmanage(true);
+        uiApp.setNodisplay(true);
+#ifdef MULTIPROCESS_SERVICE_SUPPORT_INLINE
+        uiApp.setTaskmanage(ConfigParserData::AppControlInfo::Disposition::INLINE != it->m_disposition);
+        uiApp.setMultiple(ConfigParserData::AppControlInfo::Disposition::INLINE == it->m_disposition);
+#endif
+        std::stringstream postfix;
+        postfix << AppControlPrefix::PROCESS_PREFIX << it->m_index;
+        setWidgetExecPath(uiApp, postfix.str());
+        setWidgetName(manifest, uiApp);
+        setWidgetIds(manifest, uiApp);
+        setWidgetIcons(uiApp);
+        setAppControlInfo(uiApp, *it);
+        setAppCategory(uiApp);
+        setMetadata(uiApp);
+        manifest.addUiApplication(uiApp);
+    }
+    // TODO: Must fix again with right method
+    // The mainapp attiribute must be set
+    // when there are multiple uiapps in mainfest
+#ifdef SERVICE_ENABLED
+    WrtDB::ConfigParserData::ServiceAppInfoList service = m_context.widgetConfig.configInfo.serviceAppInfoList;
+
+    if (service.size() > 0) {
+        ConfigParserData &data = m_context.widgetConfig.configInfo;
+
+        FOREACH(it, service) {
+            ServiceApplication serviceApp;
+            setServiceInfo(serviceApp, *it);
+            manifest.addServiceApplication(serviceApp);
+        }
+    } else {
+        _D("Widget doesn't contain service");
+    }
+#endif
+
+#ifdef IME_ENABLED
+    ImeApplication imeApp;
+    WrtDB::ConfigParserData::ImeAppInfoList ime = m_context.widgetConfig.configInfo.imeAppInfoList;
+
+    if (ime.size() > 0) {
+        extractImeInfo(imeApp);
+        manifest.addImeApplication(imeApp);
+    } else {
+        _D("Widget doesn't contain ime");
+    }
+#endif
+
+#ifdef DBOX_ENABLED
+    setLiveBoxInfo(manifest);
+#endif
+#else
+    //default widget content
+    setWidgetExecPath(uiApp);
+    setWidgetName(manifest, uiApp);
+    setWidgetIds(manifest, uiApp);
+    setWidgetIcons(uiApp);
+    setWidgetDescription(manifest);
+    setWidgetManifest(manifest);
+    setWidgetOtherInfo(uiApp);
+    setAppControlsInfo(uiApp);
+    setAppCategory(uiApp);
+    setMetadata(uiApp);
+    // move to the last of this procedure
+    //setLiveBoxInfo(manifest);
+    setAccount(manifest);
+    setPrivilege(manifest);
+
+    manifest.addUiApplication(uiApp);
+    // TODO: Must fix again with right method
+    // The mainapp attiribute must be set
+    // when there are multiple uiapps in mainfest
+
+#ifdef SERVICE_ENABLED
+    WrtDB::ConfigParserData::ServiceAppInfoList service = m_context.widgetConfig.configInfo.serviceAppInfoList;
+
+    if (service.size() > 0) {
+        ConfigParserData &data = m_context.widgetConfig.configInfo;
+
+        FOREACH(it, service) {
+            ServiceApplication serviceApp;
+            setServiceInfo(serviceApp, *it);
+            manifest.addServiceApplication(serviceApp);
+        }
+    } else {
+        _D("Widget doesn't contain service");
+    }
+#endif
+
+#ifdef IME_ENABLED
+    ImeApplication imeApp;
+    WrtDB::ConfigParserData::ImeAppInfoList ime = m_context.widgetConfig.configInfo.imeAppInfoList;
+
+    if (ime.size() > 0) {
+        extractImeInfo(imeApp);
+        manifest.addImeApplication(imeApp);
+    } else {
+        _D("Widget doesn't contain ime");
+    }
+#endif
+
+#ifdef DBOX_ENABLED
+    setLiveBoxInfo(manifest);
+#endif
+#endif
+
+    manifest.generate(path);
+    _D("Manifest file serialized");
+}
+
+#ifdef SERVICE_ENABLED
+void TaskManifestFile::setServiceInfo(ServiceApplication &serviceApp, WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    setWidgetExecPathService(serviceApp, service);
+    setWidgetIdsService(serviceApp, service);
+    setWidgetNameService(serviceApp, service);
+    setWidgetIconService(serviceApp, service);
+    setAppControlsInfoService(serviceApp);
+    setWidgetOtherInfoService(serviceApp);
+    setWidgetComponentService(serviceApp);
+    setWidgetAutoRestartService(serviceApp, service);
+    setWidgetOnBootService(serviceApp, service);
+}
+
+void TaskManifestFile::setWidgetComponentService(ServiceApplication &serviceApp)
+{
+    serviceApp.setComponent(DPL::FromASCIIString("svcapp"));
+}
+
+void TaskManifestFile::setWidgetAutoRestartService(ServiceApplication &serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    serviceApp.setAutoRestart(service.autoRestart);
+}
+
+void TaskManifestFile::setWidgetOnBootService(ServiceApplication &serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    serviceApp.setOnBoot(service.onBoot);
+}
+
+void TaskManifestFile::setWidgetExecPathService(ServiceApplication &serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    if (service.serviceId.empty()) {
+        _D("Widget doesn't contain service id");
+        return;
+    }
+
+    std::string serviceExec = m_context.locations->getBinaryDir() + "/" + DPL::ToUTF8String(service.serviceId);
+    serviceApp.setExec(DPL::FromUTF8String(serviceExec));
+}
+
+void TaskManifestFile::setWidgetIdsService(ServiceApplication &serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    //appid
+    if (service.serviceId.empty()) {
+        _D("Widget doesn't contain service id");
+        return;
+    }
+    serviceApp.setAppid(service.serviceId);
+
+    //extraid
+    TizenAppId appid = m_context.widgetConfig.tzAppid;
+    if (!!m_context.widgetConfig.guid) {
+        serviceApp.setExtraid(*m_context.widgetConfig.guid);
+    } else {
+        if (!appid.empty()) {
+            serviceApp.setExtraid(DPL::String(L"http://") + appid);
+        }
+    }
+
+    //type
+    serviceApp.setType(DPL::FromASCIIString("capp"));
+}
+
+void TaskManifestFile::setWidgetNameService(ServiceApplication &serviceApp, WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    if (service.m_localizedDataSet.empty()) {
+        _D("Widget doesn't contain service name");
+        return;
+    }
+
+    ConfigParserData::LocalizedDataSet &localizedDataSet = service.m_localizedDataSet;
+    FOREACH(localizedData, localizedDataSet) {
+        Locale i = localizedData->first;
+        DPL::OptionalString localeTag = getLangTag(i);
+        if (localeTag.IsNull()) {
+            localeTag = i;
+        }
+        DPL::OptionalString name = localizedData->second.name;
+
+        if (!!name) {
+            if (!!localeTag) {
+                DPL::String locale =
+                    LanguageTagsProvider::BCP47LanguageTagToLocale(*localeTag);
+
+                if (!locale.empty()) {
+                    serviceApp.addLabel(LabelType(*name, *localeTag));
+                } else {
+                    serviceApp.addLabel(LabelType(*name));
+                }
+            } else {
+                serviceApp.addLabel(LabelType(*name));
+            }
+        }
+    }
+}
+
+void TaskManifestFile::setWidgetIconService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service)
+{
+    if (service.m_iconsList.empty()) {
+        _D("Widget doesn't contain service icon");
+        return;
+    }
+
+    DPL::String icon =
+        DPL::FromUTF8String(m_context.locations->getSharedResourceDir()) +
+        DPL::String(L"/") +
+        DPL::String(service.serviceId) + DPL::String(L".png");
+    serviceApp.addIcon(icon);
+}
+
+void TaskManifestFile::setAppControlsInfoService(ServiceApplication & serviceApp)
+{
+    WrtDB::ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+
+    if (appControlList.empty()) {
+        _D("Widget doesn't contain app control");
+        return;
+    }
+
+     // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    FOREACH(it, appControlList) {
+        setAppControlInfoService(serviceApp, *it);
+    }
+}
+
+void TaskManifestFile::setAppControlInfoService(ServiceApplication & serviceApp,
+                                         const WrtDB::ConfigParserData::AppControlInfo & service)
+{
+    // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    AppControl appControl;
+    if (!service.m_operation.empty()) {
+        appControl.addOperation(service.m_operation); //TODO: encapsulation?
+    }
+    if (!service.m_uriList.empty()) {
+        FOREACH(uri, service.m_uriList) {
+            appControl.addUri(*uri);
+        }
+    }
+    if (!service.m_mimeList.empty()) {
+        FOREACH(mime, service.m_mimeList) {
+            appControl.addMime(*mime);
+        }
+    }
+    serviceApp.addAppControl(appControl);
+}
+
+void TaskManifestFile::setWidgetOtherInfoService(ServiceApplication &serviceApp)
+{
+    serviceApp.setNodisplay(true);
+    serviceApp.setTaskmanage(false);
+    serviceApp.setMultiple(false);
+
+    FOREACH(it, m_context.widgetConfig.configInfo.settingsList)
+    {
+        if (!strcmp(DPL::ToUTF8String(it->m_name).c_str(), STR_NODISPLAY)) {
+            if (!strcmp(DPL::ToUTF8String(it->m_value).c_str(), STR_TRUE)) {
+                serviceApp.setNodisplay(true);
+                serviceApp.setTaskmanage(false);
+            } else {
+                serviceApp.setNodisplay(false);
+                serviceApp.setTaskmanage(true);
+            }
+        }
+    }
+}
+#endif
+
+#ifdef IME_ENABLED
+void TaskManifestFile::extractImeInfo(ImeApplication &imeApp)
+{
+    setWidgetNameIME(imeApp);
+    setWidgetIdsIME(imeApp);
+    setWidgetUuidIME(imeApp);
+    setWidgetLanguageIME(imeApp);
+    setWidgetTypeIME(imeApp);
+    setWidgetOptionIME(imeApp);
+}
+
+void TaskManifestFile::setWidgetUuidIME(ImeApplication &imeApp)
+{
+    WrtDB::ConfigParserData::ImeAppInfoList ime = m_context.widgetConfig.configInfo.imeAppInfoList;
+
+    FOREACH(it, ime)
+    {
+        imeApp.addUuid(it->uuid);
+    }
+}
+
+void TaskManifestFile::setWidgetLanguageIME(ImeApplication &imeApp)
+{
+    WrtDB::ConfigParserData::ImeAppInfoList ime = m_context.widgetConfig.configInfo.imeAppInfoList;
+
+    FOREACH(it, ime)
+    {
+        FOREACH(lang, it->languageList) {
+            imeApp.addLanguage(*lang);
+        }
+    }
+}
+
+void TaskManifestFile::setWidgetTypeIME(ImeApplication &imeApp)
+{
+    imeApp.addIseType(DPL::FromASCIIString("SOFTWARE_KEYBOARD_ISE"));
+}
+
+void TaskManifestFile::setWidgetOptionIME(ImeApplication &imeApp)
+{
+    imeApp.addOption(DPL::FromASCIIString("STAND_ALONE"));
+    imeApp.addOption(DPL::FromASCIIString("NEED_SCREEN_INFO"));
+    imeApp.addOption(DPL::FromASCIIString("AUTO_RESTART"));
+}
+
+void TaskManifestFile::setWidgetIdsIME(ImeApplication & imeApp, const std::string &postfix)
+{
+    //appid
+    TizenAppId appid = m_context.widgetConfig.tzAppid;
+    if (!postfix.empty()) {
+        appid = DPL::FromUTF8String(DPL::ToUTF8String(appid).append(postfix));
+    }
+    imeApp.setAppid(appid);
+}
+
+void TaskManifestFile::setWidgetNameIME(ImeApplication &imeApp)
+{
+    bool defaultNameSaved = false;
+
+    DPL::OptionalString defaultLocale =
+        m_context.widgetConfig.configInfo.defaultlocale;
+    std::pair<DPL::String,
+              WrtDB::ConfigParserData::LocalizedData> defaultLocalizedData;
+    //labels
+    FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
+        if (!tag) {
+            tag = i;
+        }
+        DPL::OptionalString name = localizedData->second.name;
+        generateWidgetNameIME(imeApp, tag, name, defaultNameSaved);
+
+        //store default locale localized data
+        if (!!defaultLocale && defaultLocale == i) {
+            defaultLocalizedData = *localizedData;
+        }
+    }
+
+    if (!!defaultLocale && !defaultNameSaved) {
+        DPL::OptionalString name = defaultLocalizedData.second.name;
+        generateWidgetNameIME(imeApp,
+                           DPL::OptionalString(),
+                           name,
+                           defaultNameSaved);
+    }
+}
+
+void TaskManifestFile::generateWidgetNameIME(ImeApplication &imeApp,
+                                          const DPL::OptionalString& tag,
+                                          DPL::OptionalString name,
+                                          bool & defaultNameSaved)
+{
+    if (!!name) {
+        if (!!tag) {
+            DPL::String locale =
+                LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+
+            if (!locale.empty()) {
+                imeApp.addLabel(LabelType(*name, *tag));
+            } else {
+                imeApp.addLabel(LabelType(*name));
+            }
+        } else {
+            defaultNameSaved = true;
+            imeApp.addLabel(LabelType(*name));
+        }
+    }
+}
+#endif
+
+void TaskManifestFile::setWidgetExecPath(UiApplication & uiApp,
+                                         const std::string &postfix)
+{
+    std::string exec = m_context.locations->getExecFile();
+    if (!postfix.empty()) {
+        exec.append(postfix);
+    }
+    _D("exec = %s", exec.c_str());
+    uiApp.setExec(DPL::FromASCIIString(exec));
+}
+
+void TaskManifestFile::setWidgetName(Manifest & manifest,
+                                     UiApplication & uiApp)
+{
+    bool defaultNameSaved = false;
+
+    DPL::OptionalString defaultLocale =
+        m_context.widgetConfig.configInfo.defaultlocale;
+    std::pair<DPL::String,
+              WrtDB::ConfigParserData::LocalizedData> defaultLocalizedData;
+    //labels
+    FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
+        if (!tag) {
+            tag = i;
+        }
+        DPL::OptionalString name = localizedData->second.name;
+        generateWidgetName(manifest, uiApp, tag, name, defaultNameSaved);
+
+        //store default locale localized data
+        if (!!defaultLocale && defaultLocale == i) {
+            defaultLocalizedData = *localizedData;
+        }
+    }
+
+    if (!!defaultLocale && !defaultNameSaved) {
+        DPL::OptionalString name = defaultLocalizedData.second.name;
+        generateWidgetName(manifest,
+                           uiApp,
+                           DPL::OptionalString(),
+                           name,
+                           defaultNameSaved);
+    }
+}
+
+void TaskManifestFile::setWidgetIds(Manifest & manifest,
+                                    UiApplication & uiApp,
+                                    const std::string &postfix)
+{
+    //appid
+    TizenAppId appid = m_context.widgetConfig.tzAppid;
+    if (!postfix.empty()) {
+        appid = DPL::FromUTF8String(DPL::ToUTF8String(appid).append(postfix));
+    }
+    uiApp.setAppid(appid);
+
+    //extraid
+    if (!!m_context.widgetConfig.guid) {
+        uiApp.setExtraid(*m_context.widgetConfig.guid);
+    } else {
+        if (!appid.empty()) {
+            uiApp.setExtraid(DPL::String(L"http://") + appid);
+        }
+    }
+
+    //type
+    uiApp.setType(DPL::FromASCIIString("webapp"));
+    manifest.setType(L"wgt");
+}
+
+void TaskManifestFile::generateWidgetName(Manifest & manifest,
+                                          UiApplication &uiApp,
+                                          const DPL::OptionalString& tag,
+                                          DPL::OptionalString name,
+                                          bool & defaultNameSaved)
+{
+    if (!!name) {
+        if (!!tag) {
+            DPL::String locale =
+                LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+
+            if (!locale.empty()) {
+                uiApp.addLabel(LabelType(*name, *tag));
+            } else {
+                uiApp.addLabel(LabelType(*name));
+                manifest.addLabel(LabelType(*name));
+            }
+        } else {
+            defaultNameSaved = true;
+            uiApp.addLabel(LabelType(*name));
+            manifest.addLabel(LabelType(*name));
+        }
+    }
+}
+
+void TaskManifestFile::setWidgetIcons(UiApplication & uiApp)
+{
+    //TODO this file will need to be updated when user locale preferences
+    //changes.
+    bool defaultIconSaved = false;
+
+    DPL::OptionalString defaultLocale =
+        m_context.widgetConfig.configInfo.defaultlocale;
+
+    std::vector<Locale> generatedLocales;
+    WrtDB::WidgetRegisterInfo::LocalizedIconList & icons =
+        m_context.widgetConfig.localizationData.icons;
+
+    for (WrtDB::WidgetRegisterInfo::LocalizedIconList::const_iterator
+         icon = icons.begin();
+         icon != icons.end();
+         ++icon)
+    {
+        FOREACH(locale, icon->availableLocales)
+        {
+            DPL::String tmp = (icon->isSmall ? L"small_" : L"") + (*locale);
+            if (std::find(generatedLocales.begin(), generatedLocales.end(),
+                          tmp) != generatedLocales.end())
+            {
+                _D("Skipping - has that locale - already in manifest");
+                continue;
+            } else {
+                generatedLocales.push_back(tmp);
+            }
+            DPL::OptionalString tag = getLangTag(*locale); // translate en ->
+                                                           // en_US etc
+            if (!tag) {
+                tag = *locale;
+            }
+
+            generateWidgetIcon(uiApp, tag, *locale, DPL::Utils::Path(icon->src).Extension(), icon->isSmall, defaultIconSaved);
+        }
+    }
+    if (!!defaultLocale && !defaultIconSaved) {
+        generateWidgetIcon(uiApp, DPL::OptionalString(),
+                           DPL::String(),
+                           std::string(),
+                           false,
+                           defaultIconSaved);
+    }
+}
+
+void TaskManifestFile::generateWidgetIcon(UiApplication & uiApp,
+                                          const DPL::OptionalString& tag,
+                                          const DPL::String& language,
+                                          const std::string & extension,
+                                          bool isSmall,
+                                          bool & defaultIconSaved)
+{
+    DPL::String locale;
+    if (!!tag) {
+        locale = LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+    } else {
+        defaultIconSaved = true;
+    }
+
+    DPL::Utils::Path
+        iconText(m_context.locations->getSharedResourceDir());
+    iconText /= (isSmall ? L"small_" : L"") + getIconTargetFilename(language, extension);
+
+    if (!locale.empty()) {
+        uiApp.addIcon(IconType(DPL::FromUTF8String(iconText.Fullpath()), locale, isSmall));
+    } else {
+        uiApp.addIcon(IconType(DPL::FromUTF8String(iconText.Fullpath()), isSmall));
+    }
+
+    _D("Icon file : %s", iconText.Fullpath().c_str());
+    m_context.job->SendProgressIconPath(iconText.Fullpath());
+}
+
+void TaskManifestFile::setWidgetDescription(Manifest & manifest)
+{
+    FOREACH(localizedData, m_context.widgetConfig.configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        DPL::OptionalString tag = getLangTag(i); // translate en -> en_US etc
+        if (!tag) {
+            tag = i;
+        }
+        DPL::OptionalString description = localizedData->second.description;
+        generateWidgetDescription(manifest, tag, description);
+    }
+}
+
+void TaskManifestFile::generateWidgetDescription(Manifest & manifest,
+                                                 const DPL::OptionalString& tag,
+                                                  DPL::OptionalString description)
+{
+    if (!!description) {
+        if (!!tag) {
+            DPL::String locale =
+                LanguageTagsProvider::BCP47LanguageTagToLocale(*tag);
+            if (!locale.empty()) {
+                manifest.addDescription(DescriptionType(*description, locale));
+            } else {
+                manifest.addDescription(DescriptionType(*description));
+            }
+        } else {
+            manifest.addDescription(DescriptionType(*description));
+        }
+    }
+}
+
+void TaskManifestFile::setWidgetManifest(Manifest & manifest)
+{
+    manifest.setPackage(m_context.widgetConfig.tzPkgid);
+
+    if (!!m_context.widgetConfig.version) {
+        manifest.setVersion(*m_context.widgetConfig.version);
+    }
+    DPL::String email = (!!m_context.widgetConfig.configInfo.authorEmail ?
+                         *m_context.widgetConfig.configInfo.authorEmail : L"");
+    DPL::String href = (!!m_context.widgetConfig.configInfo.authorHref ?
+                        *m_context.widgetConfig.configInfo.authorHref : L"");
+    DPL::String name = (!!m_context.widgetConfig.configInfo.authorName ?
+                        *m_context.widgetConfig.configInfo.authorName : L"");
+    manifest.addAuthor(Author(email, href, L"", name));
+
+    if (!m_context.callerPkgId.empty()) {
+        manifest.setStoreClientId(m_context.callerPkgId);
+    }
+
+    // set csc path
+    if (!m_context.mode.cscPath.empty()) {
+        manifest.setCscPath(DPL::FromUTF8String(m_context.mode.cscPath));
+    }
+}
+
+void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp)
+{
+    FOREACH(it, m_context.widgetConfig.configInfo.settingsList)
+    {
+        if (!strcmp(DPL::ToUTF8String(it->m_name).c_str(), STR_NODISPLAY)) {
+            if (!strcmp(DPL::ToUTF8String(it->m_value).c_str(), STR_TRUE)) {
+                uiApp.setNodisplay(true);
+                uiApp.setTaskmanage(false);
+            } else {
+                uiApp.setNodisplay(false);
+                uiApp.setTaskmanage(true);
+            }
+        }
+    }
+    //TODO
+    //There is no "X-TIZEN-PackageType=wgt"
+    //There is no X-TIZEN-PackageID in manifest "X-TIZEN-PackageID=" <<
+    // DPL::ToUTF8String(*widgetID).c_str()
+    //There is no Comment in pkgmgr "Comment=Widget application"
+    //that were in desktop file
+}
+
+void TaskManifestFile::setAppControlsInfo(UiApplication & uiApp)
+{
+    WrtDB::ConfigParserData::AppControlInfoList appControlList =
+        m_context.widgetConfig.configInfo.appControlList;
+
+    if (appControlList.empty()) {
+        _D("Widget doesn't contain app control");
+        return;
+    }
+
+     // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    FOREACH(it, appControlList) {
+        setAppControlInfo(uiApp, *it);
+    }
+}
+
+void TaskManifestFile::setAppControlInfo(UiApplication & uiApp,
+                                         const WrtDB::ConfigParserData::AppControlInfo & service)
+{
+    // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image;
+    AppControl appControl;
+    if (!service.m_operation.empty()) {
+        appControl.addOperation(service.m_operation); //TODO: encapsulation?
+    }
+    if (!service.m_uriList.empty()) {
+        FOREACH(uri, service.m_uriList) {
+            appControl.addUri(*uri);
+        }
+    }
+    if (!service.m_mimeList.empty()) {
+        FOREACH(mime, service.m_mimeList) {
+            appControl.addMime(*mime);
+        }
+    }
+    uiApp.addAppControl(appControl);
+}
+
+void TaskManifestFile::setAppCategory(UiApplication &uiApp)
+{
+    WrtDB::ConfigParserData::CategoryList categoryList =
+        m_context.widgetConfig.configInfo.categoryList;
+
+    bool hasPredefinedCategory = false;
+    FOREACH(it, categoryList) {
+        if (!(*it).empty()) {
+            uiApp.addAppCategory(*it);
+            if (DPL::ToUTF8String(*it) == STR_CATEGORY_WATCH_CLOCK) {
+                // in case of idle clock,
+                // nodisplay should be set to true
+                uiApp.setNodisplay(true);
+                uiApp.setTaskmanage(false);
+                hasPredefinedCategory = true;
+            }
+#ifdef IME_ENABLED
+            else if (DPL::ToUTF8String(*it) == STR_CATEGORY_IME) {
+                uiApp.setNodisplay(true);
+                uiApp.setTaskmanage(false);
+                hasPredefinedCategory = true;
+            }
+#endif
+#ifdef SERVICE_ENABLED
+            else if (DPL::ToUTF8String(*it) == STR_CATEGORY_SERVICE) {
+                //uiApp.setNodisplay(true);
+                //uiApp.setTaskmanage(false);
+                hasPredefinedCategory = true;
+            }
+#endif
+            else if (DPL::ToUTF8String(*it) == STR_CATEGORY_WATCH_APP) {
+                hasPredefinedCategory = true;
+            }
+        }
+    }
+
+    // Tizen W feature
+    // Add default app category (watch_app) except for watch_clock
+    if(!hasPredefinedCategory) {
+        // If the nodisplay attribute is true, does not insert any predefined category.
+        // Some preloaded applications (like font package) shouldn't be visible
+        // in app-tray and host-manager.
+        // But, the nodisplay attribute can be set by "partner" or "platform" privilege only.
+        if (!uiApp.isNoDisplay()) {
+            uiApp.addAppCategory(DPL::FromASCIIString(STR_CATEGORY_WATCH_APP));
+        }
+    }
+}
+
+void TaskManifestFile::setMetadata(UiApplication &uiApp)
+{
+    WrtDB::ConfigParserData::MetadataList metadataList =
+        m_context.widgetConfig.configInfo.metadataList;
+
+    if (metadataList.empty()) {
+        _D("Web application doesn't contain metadata");
+        return;
+    }
+    FOREACH(it, metadataList) {
+        MetadataType metadataType(it->key, it->value);
+        uiApp.addMetadata(metadataType);
+    }
+}
+
+#ifdef DBOX_ENABLED
+void TaskManifestFile::setLiveBoxInfo(Manifest& manifest)
+{
+    ConfigParserData::LiveboxList& liveboxList =
+        m_context.widgetConfig.configInfo.m_livebox;
+
+    if (liveboxList.empty()) {
+        _D("no livebox");
+        return;
+    }
+
+    if (!addBoxUiApplication(manifest)) {
+        _D("error during adding UiApplication for d-box");
+        return;
+    }
+
+    FOREACH(it, liveboxList) {
+        _D("setLiveBoxInfo");
+        LiveBoxInfo liveBox;
+        WrtDB::ConfigParserData::OptionalLiveboxInfo ConfigInfo = *it;
+        DPL::String appid = m_context.widgetConfig.tzAppid;
+
+        if (ConfigInfo->m_liveboxId != L"") {
+            liveBox.setLiveboxId(ConfigInfo->m_liveboxId);
+        }
+
+        if (ConfigInfo->m_primary != L"") {
+            liveBox.setPrimary(ConfigInfo->m_primary);
+        }
+
+        if (ConfigInfo->m_autoLaunch != L"") {
+            liveBox.setAutoLaunch(ConfigInfo->m_autoLaunch);
+        }
+
+        if (ConfigInfo->m_updatePeriod != L"") {
+            liveBox.setUpdatePeriod(ConfigInfo->m_updatePeriod);
+        }
+
+        std::list<std::pair<DPL::String, DPL::String> > boxLabelList;
+        if (!ConfigInfo->m_label.empty()) {
+            FOREACH(im, ConfigInfo->m_label) {
+                std::pair<DPL::String, DPL::String> boxSize;
+                Locale i = (*im).first;
+                // translate en -> en_US etc
+                DPL::OptionalString tag = getLangTag(i);
+                if (!tag) {
+                    tag = i;
+                }
+                boxSize.first = (*tag);
+                boxSize.second = (*im).second;
+                boxLabelList.push_back(boxSize);
+            }
+            liveBox.setLabel(boxLabelList);
+        }
+
+        DPL::String defaultLocale =
+            DPL::FromUTF8String(m_context.locations->getPackageInstallationDir()) +
+            DPL::String(L"/res/wgt/");
+
+        if (ConfigInfo->m_icon != L"") {
+            DPL::String icon =
+                DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
+                DPL::String(L"/") +
+                ConfigInfo->m_liveboxId + DPL::String(L".icon.png");
+            liveBox.setIcon(icon);
+        }
+
+        if (ConfigInfo->m_boxInfo.m_boxSrc.empty() ||
+            ConfigInfo->m_boxInfo.m_boxSize.empty())
+        {
+            _D("Widget doesn't contain box");
+            return;
+        } else {
+            BoxInfoType box;
+            if (!ConfigInfo->m_boxInfo.m_boxSrc.empty()) {
+                if ((0 == ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 4, L"http"))
+                    || (0 ==
+                        ConfigInfo->m_boxInfo.m_boxSrc.compare(0, 5, L"https")))
+                {
+                    box.boxSrc = ConfigInfo->m_boxInfo.m_boxSrc;
+                } else {
+                    box.boxSrc = defaultLocale + ConfigInfo->m_boxInfo.m_boxSrc;
+                }
+            }
+
+            if (ConfigInfo->m_boxInfo.m_boxMouseEvent == L"true") {
+                std::string boxType;
+                if (ConfigInfo->m_type == L"") {
+                    // in case of default livebox
+                    boxType = web_provider_livebox_get_default_type();
+                } else {
+                    boxType = DPL::ToUTF8String(ConfigInfo->m_type);
+                }
+
+                int box_scrollable =
+                    web_provider_plugin_get_box_scrollable(boxType.c_str());
+
+                if (box_scrollable) {
+                    box.boxMouseEvent = L"true";
+                } else {
+                    box.boxMouseEvent = L"false";
+                }
+            } else {
+                box.boxMouseEvent = L"false";
+            }
+
+            if (ConfigInfo->m_boxInfo.m_boxTouchEffect == L"true") {
+                box.boxTouchEffect = L"true";
+            } else {
+                box.boxTouchEffect= L"false";
+            }
+
+            ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+                ConfigInfo->m_boxInfo.m_boxSize;
+            FOREACH(it, boxSizeList) {
+                if (!(*it).m_preview.empty()) {
+                    (*it).m_preview =
+                        DPL::FromUTF8String(m_context.locations->getSharedDataDir()) +
+                        DPL::String(L"/") +
+                        ConfigInfo->m_liveboxId + DPL::String(L".") +
+                        (*it).m_size + DPL::String(L".preview.png");
+                }
+                box.boxSize.push_back((*it));
+            }
+
+            if (!ConfigInfo->m_boxInfo.m_pdSrc.empty()
+                && !ConfigInfo->m_boxInfo.m_pdWidth.empty()
+                && !ConfigInfo->m_boxInfo.m_pdHeight.empty())
+            {
+                if ((0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 4, L"http"))
+                    || (0 == ConfigInfo->m_boxInfo.m_pdSrc.compare(0, 5, L"https")))
+                {
+                    box.pdSrc = ConfigInfo->m_boxInfo.m_pdSrc;
+                } else {
+                    box.pdSrc = defaultLocale + ConfigInfo->m_boxInfo.m_pdSrc;
+                }
+                box.pdWidth = ConfigInfo->m_boxInfo.m_pdWidth;
+                box.pdHeight = ConfigInfo->m_boxInfo.m_pdHeight;
+            }
+            liveBox.setBox(box);
+        }
+        manifest.addLivebox(liveBox);
+    }
+}
+#endif
+
+void TaskManifestFile::setAccount(Manifest& manifest)
+{
+    WrtDB::ConfigParserData::AccountProvider account =
+        m_context.widgetConfig.configInfo.accountProvider;
+
+    AccountProviderType provider;
+
+    if (account.m_iconSet.empty()) {
+        _D("Widget doesn't contain Account");
+        return;
+    }
+    if (account.m_multiAccountSupport) {
+        provider.multiAccount = L"true";
+    } else {
+        provider.multiAccount = L"false";
+    }
+    provider.appid = m_context.widgetConfig.tzAppid;
+
+    FOREACH(it, account.m_iconSet) {
+        std::pair<DPL::String, DPL::String> icon;
+
+        if (it->first == ConfigParserData::IconSectionType::DefaultIcon) {
+            icon.first = L"account";
+        } else if (it->first == ConfigParserData::IconSectionType::SmallIcon) {
+            icon.first = L"account-small";
+        }
+
+        // account manifest requires absolute path for icon
+        // /opt/apps/[package]/shared/res/[icon_path]
+        icon.second = DPL::FromUTF8String(m_context.locations->getSharedResourceDir()) +
+                      DPL::String(L"/") +
+                      it->second;
+        provider.icon.push_back(icon);
+    }
+
+    FOREACH(it, account.m_displayNameSet) {
+        provider.name.push_back(LabelType(it->second, it->first));
+    }
+
+    FOREACH(it, account.m_capabilityList) {
+        provider.capability.push_back(*it);
+    }
+
+    Account accountInfo;
+    accountInfo.addAccountProvider(provider);
+    manifest.addAccount(accountInfo);
+}
+
+void TaskManifestFile::setPrivilege(Manifest& manifest)
+{
+    WrtDB::ConfigParserData::PrivilegeList privileges =
+        m_context.widgetConfig.configInfo.privilegeList;
+
+    PrivilegeType privilege;
+
+    FOREACH(it, privileges)
+    {
+        privilege.addPrivilegeName(it->name);
+    }
+
+    manifest.addPrivileges(privilege);
+}
+
+void TaskManifestFile::StartStep()
+{
+    LOGD("--------- <TaskManifestFile> : START ----------");
+}
+
+void TaskManifestFile::EndStep()
+{
+    LOGD("--------- <TaskManifestFile> : END ----------");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_manifest_file.h b/src_wearable/jobs/widget_install/task_manifest_file.h
new file mode 100755 (executable)
index 0000000..240cc40
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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_manifest_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>
+#include <dpl/optional_typedefs.h>
+
+#include <libxml2/libxml/xmlwriter.h>
+
+#include <libxml_utils.h>
+#include <widget_install/manifest.h>
+#include <dpl/localization/localization_utils.h>
+
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskManifestFile :
+    public DPL::TaskDecl<TaskManifestFile>
+{
+  public:
+
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, ManifestValidationError)
+    DECLARE_EXCEPTION_TYPE(Base, ManifestParsingError)
+
+    TaskManifestFile(InstallerContext &inCont);
+    virtual ~TaskManifestFile();
+
+  private:
+    //context data
+    InstallerContext &m_context;
+
+    //TODO stepAbort
+    //steps
+    void stepCreateExecFile();
+    void stepCopyIconFiles();
+    void stepCopyLiveboxFiles();
+    void stepCopyAccountIconFiles();
+#ifdef SERVICE_ENABLED
+    void stepCopyServiceIconFiles();
+#endif
+    void stepGenerateManifest();
+    void stepCreateLinkNPPluginsFile();
+
+    void stepAbortParseManifest();
+
+    void StartStep();
+    void EndStep();
+
+    //private data
+    std::list<std::string> icon_list; //TODO: this should be registered as
+                                      // external files
+    std::ostringstream backup_dir;
+    xmlTextWriterPtr writer;
+    DPL::String manifest_name;
+    DPL::String manifest_file;
+    std::string commit_manifest;
+
+    //private methods
+
+    void writeManifest(const DPL::String & path);
+    void commitManifest();
+
+    void setWidgetExecPath(UiApplication & uiApp,
+                           const std::string &postfix = std::string());
+    void setWidgetName(Manifest & manifest,
+                       UiApplication & uiApp);
+    void setWidgetIds(Manifest & manifest,
+                       UiApplication & uiApp,
+                       const std::string &postfix = std::string());
+    void setWidgetIcons(UiApplication & uiApp);
+    void setWidgetDescription(Manifest & manifest);
+    void setWidgetManifest(Manifest & manifest);
+    void setWidgetOtherInfo(UiApplication & uiApp);
+    void setAppControlsInfo(UiApplication & uiApp);
+    void setAppControlInfo(UiApplication & uiApp,
+                           const WrtDB::ConfigParserData::AppControlInfo & service);
+    void setAppCategory(UiApplication & uiApp);
+    void setMetadata(UiApplication & uiApp);
+    void setLiveBoxInfo(Manifest& manifest);
+    void setAccount(Manifest& uiApp);
+    void setPrivilege(Manifest& manifest);
+
+    void generateWidgetName(Manifest & manifest,
+                            UiApplication &uiApp,
+                            const DPL::OptionalString& tag,
+                            DPL::OptionalString name,
+                            bool & defaultNameSaved);
+    void generateWidgetDescription(Manifest & manifest,
+                                   const DPL::OptionalString& tag,
+                                   DPL::OptionalString description);
+    void generateWidgetIcon(UiApplication & uiApp,
+                            const DPL::OptionalString& tag,
+                            const DPL::String& language, const std::string &extension,
+                            bool isSmall, bool & defaultIconSaved);
+    void copyFile(const std::string& sourceFile,
+                  const std::string& targetFile);
+    bool addBoxUiApplication(Manifest& manifest);
+
+    //for widget update
+    DPL::String getIconTargetFilename(const DPL::String& languageTag,
+                                      const std::string & ext) const;
+
+    static void saveLocalizedKey(std::ofstream &file,
+                                 const DPL::String& key,
+                                 const DPL::String& languageTag);
+
+    static const char * encoding;
+
+#ifdef IME_ENABLED
+    void extractImeInfo(ImeApplication& imeApp);
+    void setWidgetNameIME(ImeApplication& imeApp);
+    void setWidgetIdsIME(ImeApplication& imeApp, const std::string& postfix = std::string());
+    void generateWidgetNameIME(ImeApplication& imeApp, const DPL::OptionalString& tag, DPL::OptionalString name, bool& defaultNameSaved);
+    void setWidgetUuidIME(ImeApplication& imeApp);
+    void setWidgetLanguageIME(ImeApplication& imeApp);
+    void setWidgetTypeIME(ImeApplication& imeApp);
+    void setWidgetOptionIME(ImeApplication& imeApp);
+#endif
+
+#ifdef SERVICE_ENABLED
+    void setServiceInfo(ServiceApplication& serviceApp, WrtDB::ConfigParserData::ServiceAppInfo & service);
+    void setWidgetExecPathService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service);
+    void setWidgetIdsService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service);
+    void setWidgetNameService(ServiceApplication & serviceApp, WrtDB::ConfigParserData::ServiceAppInfo & service);
+    void setWidgetIconService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service);
+    void setAppControlsInfoService(ServiceApplication & serviceApp);
+    void setAppControlInfoService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::AppControlInfo & service);
+    void setWidgetOtherInfoService(ServiceApplication & serviceApp);
+    void setWidgetComponentService(ServiceApplication & serviceApp);
+    void setWidgetAutoRestartService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service);
+    void setWidgetOnBootService(ServiceApplication & serviceApp, const WrtDB::ConfigParserData::ServiceAppInfo & service);
+#endif
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DESKTOP_FILE_H */
diff --git a/src_wearable/jobs/widget_install/task_pkg_info_update.cpp b/src_wearable/jobs/widget_install/task_pkg_info_update.cpp
new file mode 100644 (file)
index 0000000..942cca2
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * 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_pkg_info_update.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task information about package
+ * update
+ */
+#include "task_pkg_info_update.h"
+
+#include <unistd.h>
+#include <string>
+
+#include <fstream>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/foreach.h>
+#include <dpl/sstream.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <pkgmgr_installer.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <vcore/CryptoHash.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskPkgInfoUpdate::TaskPkgInfoUpdate(InstallerContext& context) :
+    DPL::TaskDecl<TaskPkgInfoUpdate>(this),
+    m_context(context)
+{
+    AddStep(&TaskPkgInfoUpdate::StartStep);
+    AddStep(&TaskPkgInfoUpdate::StepPkgInfo);
+    AddStep(&TaskPkgInfoUpdate::StepSetCertiInfo);
+    AddStep(&TaskPkgInfoUpdate::EndStep);
+    AddStep(&TaskPkgInfoUpdate::StepSetEndofInstallation);
+
+    AddAbortStep(&TaskPkgInfoUpdate::StepAbortCertiInfo);
+    AddAbortStep(&TaskPkgInfoUpdate::stepAbortParseManifest);
+}
+
+void TaskPkgInfoUpdate::StepPkgInfo()
+{
+    int code = 0;
+    char* updateTags[3] = {NULL, };
+
+    char preloadTrue[] = "preload=true";
+    char removableTrue[] = "removable=true";
+    char removableFalse[] = "removable=false";
+
+    if (InstallMode::InstallTime::CSC == m_context.mode.installTime
+        || InstallMode::InstallTime::PRELOAD == m_context.mode.installTime) {
+        updateTags[0] = preloadTrue;
+        if (m_context.mode.removable) {
+            updateTags[1] = removableTrue;
+        } else {
+            updateTags[1] = removableFalse;
+        }
+        updateTags[2] = NULL;
+    }
+
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        m_manifest += "/usr/share/packages/";
+    } else {
+        m_manifest += "/opt/share/packages/";
+    }
+    m_manifest += DPL::ToUTF8String(m_context.widgetConfig.tzPkgid) + ".xml";
+    _D("manifest file : %s", m_manifest.c_str());
+
+    if (m_context.isUpdateMode || (
+                m_context.mode.rootPath == InstallMode::RootPath::RO
+                && (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+                    || m_context.mode.installTime == InstallMode::InstallTime::FOTA)
+                && m_context.mode.extension == InstallMode::ExtensionType::DIR)) {
+
+        code = pkgmgr_parser_parse_manifest_for_upgrade(
+                m_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
+
+        if (code != 0) {
+            _E("Manifest parser error: %d", code);
+            ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
+        }
+    } else {
+        code = pkgmgr_parser_parse_manifest_for_installation(
+                m_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags);
+
+        if (code != 0) {
+            _E("Manifest parser error: %d", code);
+            ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
+        }
+    }
+
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_PKGINFO_UPDATE,
+            "Manifest Update Finished");
+    _D("Manifest parsed");
+}
+
+void TaskPkgInfoUpdate::StepSetCertiInfo()
+{
+    _D("StepSetCertiInfo");
+
+    if (pkgmgr_installer_create_certinfo_set_handle(&m_pkgHandle) < 0) {
+        _E("pkgmgrInstallerCreateCertinfoSetHandle fail");
+        ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                 "Failed to create certificate handle");
+    }
+
+    SetCertiInfo(SIGNATURE_AUTHOR);
+    SetCertiInfo(SIGNATURE_DISTRIBUTOR);
+    SetCertiInfo(SIGNATURE_DISTRIBUTOR2);
+
+    if ((pkgmgr_installer_save_certinfo(
+             const_cast<char*>(DPL::ToUTF8String(
+                                   m_context.widgetConfig.tzPkgid).c_str()),
+             m_pkgHandle)) < 0)
+    {
+        _E("pkgmgrInstallerSaveCertinfo fail");
+        ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                 "Failed to Installer Save Certinfo");
+    } else {
+        _D("Succeed to save Certinfo");
+    }
+
+    if (pkgmgr_installer_destroy_certinfo_set_handle(m_pkgHandle) < 0) {
+        _E("pkgmgrInstallerDestroyCertinfoSetHandle fail");
+    }
+}
+
+void TaskPkgInfoUpdate::SetCertiInfo(int source)
+{
+    _D("Set CertiInfo to pkgmgr : %d", source);
+    CertificateChainList certificateChainList;
+    m_context.widgetSecurity.getCertificateChainList(certificateChainList,
+            (CertificateSource)source);
+
+    FOREACH(it, certificateChainList)
+    {
+        _D("Insert certinfo to pkgmgr structure");
+
+        ValidationCore::CertificateCollection chain;
+
+        if (false == chain.load(*it)) {
+            _E("Chain is broken");
+            ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                     "Failed to Installer Save Certinfo");
+        }
+
+        if (!chain.sort()) {
+            _E("Chain failed at sorting");
+        }
+
+        ValidationCore::CertificateList list = chain.getCertificateList();
+
+        FOREACH(certIt, list)
+        {
+            pkgmgr_instcert_type instCertType = PM_SET_AUTHOR_ROOT_CERT;
+            if (source == SIGNATURE_AUTHOR) {
+                _D("set SIGNATURE_AUTHOR");
+                if ((*certIt)->isRootCert()) {
+                    instCertType = PM_SET_AUTHOR_ROOT_CERT;
+                } else {
+                    if ((*certIt)->isCA()) {
+                        instCertType = PM_SET_AUTHOR_INTERMEDIATE_CERT;
+                    } else {
+                        instCertType = PM_SET_AUTHOR_SIGNER_CERT;
+                    }
+                }
+            } else if (source == SIGNATURE_DISTRIBUTOR) {
+                _D("Set SIGNATURE_DISTRIBUTOR");
+                if ((*certIt)->isRootCert()) {
+                    instCertType = PM_SET_DISTRIBUTOR_ROOT_CERT;
+                } else {
+                    if ((*certIt)->isCA()) {
+                        instCertType = PM_SET_DISTRIBUTOR_INTERMEDIATE_CERT;
+                    } else {
+                        instCertType = PM_SET_DISTRIBUTOR_SIGNER_CERT;
+                    }
+                }
+            } else if (source == SIGNATURE_DISTRIBUTOR2) {
+                _D("Set SIGNATURE_DISTRIBUTOR2");
+                if ((*certIt)->isRootCert()) {
+                    instCertType = PM_SET_DISTRIBUTOR2_ROOT_CERT;
+                } else {
+                    if ((*certIt)->isCA()) {
+                        instCertType = PM_SET_DISTRIBUTOR2_INTERMEDIATE_CERT;
+                    } else {
+                        instCertType = PM_SET_DISTRIBUTOR2_SIGNER_CERT;
+                    }
+                }
+            } else {
+                _D("UNKNOWN..");
+            }
+            _D("cert type : %d", instCertType);
+            if ((pkgmgr_installer_set_cert_value(
+                     m_pkgHandle,
+                     instCertType,
+                     const_cast<char*>(((*certIt)->getBase64()).c_str()))) < 0)
+            {
+                _E("pkgmgrInstallerSetCertValue fail");
+                ThrowMsg(Exceptions::SetCertificateInfoFailed,
+                         "Failed to Set CertValue");
+            }
+        }
+    }
+}
+
+void TaskPkgInfoUpdate::StepAbortCertiInfo()
+{
+    if ((pkgmgr_installer_delete_certinfo(
+             const_cast<char*>(DPL::ToUTF8String(
+                                   m_context.widgetConfig.tzPkgid).c_str()))) <
+        0)
+    {
+        _E("pkgmgr_installer_delete_certinfo fail");
+    }
+}
+
+void TaskPkgInfoUpdate::StartStep()
+{
+    LOGD("--------- <TaskPkgInfoUpdate> : START ----------");
+}
+
+void TaskPkgInfoUpdate::EndStep()
+{
+    m_context.job->UpdateProgress(
+            InstallerContext::INSTALL_SET_CERTINFO,
+            "Save certinfo to pkgmgr");
+
+    LOGD("--------- <TaskPkgInfoUpdate> : END ----------");
+}
+
+void TaskPkgInfoUpdate::stepAbortParseManifest()
+{
+    _E("[Parse Manifest] Abroting....");
+
+    int code = pkgmgr_parser_parse_manifest_for_uninstallation(
+            m_manifest.c_str(), NULL);
+
+    if (0 != code) {
+        _W("Manifest parser error: %d", code);
+        ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code);
+    }
+    int ret = unlink(m_manifest.c_str());
+    if (0 != ret) {
+        _W("No manifest file found: %s", m_manifest.c_str());
+    }
+}
+
+void TaskPkgInfoUpdate::StepSetEndofInstallation()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_END,
+        "End installation");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_pkg_info_update.h b/src_wearable/jobs/widget_install/task_pkg_info_update.h
new file mode 100644 (file)
index 0000000..e1e9235
--- /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       task_pkg_info_update.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_PKG_INFO_UPDATE_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_PKG_INFO_UPDATE_H_
+
+#include <dpl/task.h>
+#include <string>
+#include <pkgmgr_installer.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskPkgInfoUpdate : public DPL::TaskDecl<TaskPkgInfoUpdate>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+
+    void StepPkgInfo();
+    void StepSetCertiInfo();
+    void SetCertiInfo(int source);
+    void StepSetEndofInstallation();
+
+    void stepAbortParseManifest();
+    void StepAbortCertiInfo();
+
+    void StartStep();
+    void EndStep();
+
+    pkgmgr_instcertinfo_h m_pkgHandle;
+    std::string m_manifest;
+
+  public:
+    explicit TaskPkgInfoUpdate(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_PKG_INFO_UPDATE_H_ */
diff --git a/src_wearable/jobs/widget_install/task_prepare_files.cpp b/src_wearable/jobs/widget_install/task_prepare_files.cpp
new file mode 100644 (file)
index 0000000..d8eac2e
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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_generate_config.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include "task_prepare_files.h"
+#include <memory>
+#include <string>
+#include <iostream>
+#include <dpl/file_output.h>
+#include <dpl/file_input.h>
+#include <dpl/copy.h>
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <dpl/foreach.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install_errors.h>
+#include <task_commons.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskPrepareFiles::TaskPrepareFiles(InstallerContext &installerContext) :
+    DPL::TaskDecl<TaskPrepareFiles>(this),
+    m_installerContext(installerContext)
+{
+    AddStep(&TaskPrepareFiles::StartStep);
+    AddStep(&TaskPrepareFiles::StepCopyFiles);
+    AddStep(&TaskPrepareFiles::EndStep);
+}
+
+void TaskPrepareFiles::CopyFile(const std::string& source)
+{
+    if (source.empty()) {
+        _W("No source file specified");
+        return;
+    }
+
+    std::string filename = source;
+    size_t last = source.find_last_of("\\/");
+    if (last != std::string::npos) {
+        filename = source.substr(last + 1);
+    }
+    std::string target =
+        m_installerContext.locations->getSourceDir() + '/' +
+        filename;
+    _D("source %s", source.c_str());
+    _D("target %s", target.c_str());
+
+    Try
+    {
+        DPL::FileInput input(source);
+        DPL::FileOutput output(target);
+        DPL::Copy(&input, &output);
+    }
+    Catch(DPL::FileInput::Exception::Base)
+    {
+        _E("File input error");
+        // Error while opening or closing source file
+        ReThrowMsg(Exceptions::CopyIconFailed, source);
+    }
+    Catch(DPL::FileOutput::Exception::Base)
+    {
+        _E("File output error");
+        // Error while opening or closing target file
+        ReThrowMsg(Exceptions::CopyIconFailed, target);
+    }
+    Catch(DPL::CopyFailed)
+    {
+        _E("File copy error");
+        // Error while copying
+        ReThrowMsg(Exceptions::CopyIconFailed, target);
+    }
+}
+
+void TaskPrepareFiles::StepCopyFiles()
+{
+    CopyFile(m_installerContext.locations->getWidgetSource());
+
+    size_t last = m_installerContext.locations->getWidgetSource().find_last_of(
+            "\\/");
+    std::string sourceDir = "";
+    if (last != std::string::npos) {
+        sourceDir = m_installerContext.locations->getWidgetSource().substr(
+                0,
+                last
+                + 1);
+    }
+
+    _D("Icons copy...");
+    FOREACH(it, m_installerContext.widgetConfig.configInfo.iconsList) {
+        std::ostringstream os;
+        _D("Coping: %s%ls", sourceDir.c_str(), (it->src).c_str());
+        os << sourceDir << DPL::ToUTF8String(it->src);
+        CopyFile(os.str());
+    }
+}
+
+void TaskPrepareFiles::StartStep()
+{
+    LOGD("--------- <TaskPrepareFiles> : START ----------");
+}
+
+void TaskPrepareFiles::EndStep()
+{
+    LOGD("--------- <TaskPrepareFiles> : END ----------");
+}
+} // namespace WidgetInstall
+} // namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_prepare_files.h b/src_wearable/jobs/widget_install/task_prepare_files.h
new file mode 100644 (file)
index 0000000..99458e8
--- /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       task_prepare_files.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_PREPARE_FILES_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_PREPARE_FILES_H_
+
+#include <dpl/task.h>
+#include <string>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskPrepareFiles : public DPL::TaskDecl<TaskPrepareFiles>
+{
+  private:
+    // Installation context
+    InstallerContext &m_installerContext;
+
+    void CopyFile(const std::string& source);
+
+    // Steps
+    void StepCopyFiles();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    explicit TaskPrepareFiles(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_PREPARE_FILES_H_ */
diff --git a/src_wearable/jobs/widget_install/task_prepare_reinstall.cpp b/src_wearable/jobs/widget_install/task_prepare_reinstall.cpp
new file mode 100644 (file)
index 0000000..97133bf
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * 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_prepare_reinstall.cpp
+ * @author  Jihoon Chung(jihoon.chung@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task prepare reinstalling
+ */
+
+#include "task_prepare_reinstall.h"
+
+#include <stdio.h>
+#include <fstream>
+#include <unistd.h>
+
+#include <dpl/task.h>
+#include <dpl/string.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/job_widget_install.h>
+
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace {
+const char* const KEY_DELETE = "#delete";
+const char* const KEY_ADD = "#add";
+const char* const KEY_MODIFY = "#modify";
+std::list<std::string> keyList = {KEY_DELETE, KEY_ADD, KEY_MODIFY};
+
+void verifyFile(const std::string &filePath)
+{
+    if (access(filePath.c_str(), F_OK) != 0) {
+        ThrowMsg(Exceptions::RDSDeltaFailure, "File is missed " << filePath);
+    }
+}
+
+std::string parseSubPath(const std::string& filePath)
+{
+    std::string subPath("");
+    size_t pos = filePath.find_last_of('/') + 1;
+
+    if (pos != std::string::npos) {
+        subPath = filePath.substr(0, pos);
+    }
+    return subPath;
+}
+
+void createDir(const std::string& path)
+{
+    if (WrtUtilMakeDir(path)) {
+        _D("Create directory : %s", path.c_str());
+    } else {
+        ThrowMsg(Exceptions::RDSDeltaFailure, "Fail to create dir" << path);
+    }
+}
+} // namespace anonymous
+
+TaskPrepareReinstall::TaskPrepareReinstall(InstallerContext& context) :
+    DPL::TaskDecl<TaskPrepareReinstall>(this),
+    m_context(context)
+{
+    AddStep(&TaskPrepareReinstall::StartStep);
+    AddStep(&TaskPrepareReinstall::StepPrepare);
+    AddStep(&TaskPrepareReinstall::StepParseRDSDelta);
+    AddStep(&TaskPrepareReinstall::StepVerifyRDSDelta);
+    AddStep(&TaskPrepareReinstall::StepAddFile);
+    AddStep(&TaskPrepareReinstall::StepDeleteFile);
+    AddStep(&TaskPrepareReinstall::StepModifyFile);
+    AddStep(&TaskPrepareReinstall::EndStep);
+}
+
+void TaskPrepareReinstall::StepPrepare()
+{
+    _D("Prepare");
+    m_sourcePath = m_context.locations->getTemporaryPackageDir();
+    m_sourcePath += "/";
+
+    m_installedPath = m_context.locations->getPackageInstallationDir();
+    m_installedPath += "/";
+}
+
+void TaskPrepareReinstall::StepParseRDSDelta()
+{
+    _D("parse RDS delta");
+    std::string rdsDeltaPath = m_sourcePath;
+    rdsDeltaPath += ".rds_delta";
+    std::ifstream delta(rdsDeltaPath);
+
+    if (!delta.is_open()) {
+        ThrowMsg(Exceptions::RDSDeltaFailure, "rds_delta file is missed");
+        return;
+    }
+
+    std::string line;
+    std::string key;
+    while (std::getline(delta, line) &&!delta.eof()) {
+        FOREACH(keyIt, keyList) {
+            if (line == *keyIt) {
+                _D("find key = [%s]", line.c_str());
+                key = line;
+                break;
+            }
+        }
+        if (key == line || line.empty() || line == "\n") {
+            continue;
+        }
+        if (key == KEY_DELETE) {
+            m_deleteFileList.push_back(line);
+            _D("line = [%s]", line.c_str());
+        } else if (key == KEY_ADD) {
+            m_addFileList.push_back(line);
+            _D("line = [%s]", line.c_str());
+        } else if (key == KEY_MODIFY) {
+            m_modifyFileList.push_back(line);
+            _D("line = [%s]", line.c_str());
+        }
+    }
+}
+
+void TaskPrepareReinstall::StepVerifyRDSDelta()
+{
+    _D("verify RDS delta");
+    // Verify ADD file
+    FOREACH(file, m_addFileList) {
+        std::string addFilePath = m_sourcePath;
+        addFilePath += *file;
+        verifyFile(addFilePath);
+    }
+    // Verify DELETE file
+    FOREACH(file, m_deleteFileList) {
+        std::string deleteFilePath = m_installedPath;
+        deleteFilePath += *file;
+        verifyFile(deleteFilePath);
+    }
+    // Verify MODIFY file
+    FOREACH(file, m_modifyFileList) {
+        std::string newFilePath = m_sourcePath;
+        newFilePath += *file;
+        verifyFile(newFilePath);
+
+        std::string existingFilePath = m_installedPath;
+        existingFilePath += *file;
+        verifyFile(existingFilePath);
+    }
+    _D("Finished veify RDS Delta");
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_RDS_DELTA_CHECK,
+        "RDS delta verify finished");
+}
+
+void TaskPrepareReinstall::StepAddFile()
+{
+    _D("Add file");
+    FOREACH(file, m_addFileList) {
+        std::string newfile = m_sourcePath;
+        newfile += *file;
+        std::string destPath = m_installedPath;
+        destPath += *file;
+
+        if (WrtUtilDirExists(newfile)) {
+            // In case of a new directory
+            createDir(destPath);
+        } else {
+            // In case of a new file
+
+            // Parse directory and file separately
+            std::string subPath = parseSubPath(destPath);
+            if (subPath.empty()) {
+                ThrowMsg(Exceptions::RDSDeltaFailure,
+                         "Invalid path given" << destPath);
+            }
+
+            // Create a new directory
+            createDir(subPath);
+
+            // Add file
+            if (rename(newfile.c_str(), destPath.c_str()) != 0) {
+                ThrowMsg(Exceptions::RDSDeltaFailure,
+                        "Fail to add file " << newfile);
+            }
+            _D("Add %s to %s", newfile.c_str(), destPath.c_str());
+        }
+    }
+}
+
+void TaskPrepareReinstall::StepDeleteFile()
+{
+    _D("Delete file");
+    FOREACH(file, m_deleteFileList) {
+        std::string deleteFilePath = m_installedPath;
+        deleteFilePath += *file;
+        if (remove(deleteFilePath.c_str()) != 0) {
+            ThrowMsg(Exceptions::RDSDeltaFailure,
+                "Fail to DELETE file " << deleteFilePath);
+        }
+        _D("Delete %s", deleteFilePath.c_str());
+    }
+}
+
+void TaskPrepareReinstall::StepModifyFile()
+{
+    _D("Modify  file");
+    FOREACH(file, m_modifyFileList) {
+        std::string destPath = m_installedPath;
+        destPath += *file;
+        if (remove(destPath.c_str()) != 0) {
+            ThrowMsg(Exceptions::RDSDeltaFailure,
+                "Fail to delete existing file " << destPath);
+        }
+
+        std::string newfile = m_sourcePath;
+        newfile += *file;
+        if (rename(newfile.c_str(), destPath.c_str()) != 0) {
+            ThrowMsg(Exceptions::RDSDeltaFailure,
+                "Fail to move new file" << destPath);
+        }
+        _D("Replace %s to %s", newfile.c_str(), destPath.c_str());
+    }
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_RDS_PREPARE,
+        "RDS prepare finished");
+}
+
+void TaskPrepareReinstall::StartStep()
+{
+    LOGD("---------- <TaskPrepareReinstall> : START ----------");
+}
+
+void TaskPrepareReinstall::EndStep()
+{
+    LOGD("---------- <TaskPrepareReinstall> : END ----------");
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_END,
+        "End RDS update");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_prepare_reinstall.h b/src_wearable/jobs/widget_install/task_prepare_reinstall.h
new file mode 100644 (file)
index 0000000..2828f27
--- /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_prepare_reinstall.h
+ * @author  Jihoon Chung(jihoon.chung@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task prepare reinstalling
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PREPARE_REINSTALL_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PREPARE_REINSTALL_H
+
+#include <list>
+#include <dpl/task.h>
+
+#include <widget_install/widget_install_context.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskPrepareReinstall :
+    public DPL::TaskDecl<TaskPrepareReinstall>
+{
+  public:
+    TaskPrepareReinstall(InstallerContext& context);
+
+  private:
+    // install internal location
+    void StepPrepare();
+    void StepParseRDSDelta();
+    void StepVerifyRDSDelta();
+    void StepAddFile();
+    void StepDeleteFile();
+    void StepModifyFile();
+
+    void StepAbortPrepareReinstall();
+
+    void StartStep();
+    void EndStep();
+
+    InstallerContext& m_context;
+    // TODO : replace multimap
+    std::list<std::string> m_addFileList;
+    std::list<std::string> m_deleteFileList;
+    std::list<std::string> m_modifyFileList;
+    std::string m_sourcePath;
+    std::string m_installedPath;
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PREPARE_REINSTALL_H
diff --git a/src_wearable/jobs/widget_install/task_process_config.cpp b/src_wearable/jobs/widget_install/task_process_config.cpp
new file mode 100755 (executable)
index 0000000..4198f4d
--- /dev/null
@@ -0,0 +1,695 @@
+/*
+ * 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_process_config.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task widget config
+ */
+
+#include <string>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+#include <dpl/localization/w3c_file_localization.h>
+#include <dpl/singleton_impl.h>
+#include <dpl/utils/mime_type_utils.h>
+#include <dpl/utils/wrt_global_settings.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-rw/feature_dao.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_process_config.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_parser.h>
+#ifdef DBOX_ENABLED
+#include <web_provider_plugin_info.h>
+#include <web_provider_livebox_info.h>
+#endif
+#include <manifest.h>
+
+#include <installer_log.h>
+
+namespace { // anonymous
+const DPL::String BR = DPL::FromUTF8String("<br>");
+const std::string WINDGET_INSTALL_NETWORK_ACCESS = "network access";
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+
+TaskProcessConfig::TaskProcessConfig(InstallerContext& installContext) :
+    DPL::TaskDecl<TaskProcessConfig>(this),
+    m_installContext(installContext)
+{
+    AddStep(&TaskProcessConfig::StartStep);
+    AddStep(&TaskProcessConfig::ReadLocaleFolders);
+    AddStep(&TaskProcessConfig::StepFillWidgetConfig);
+    AddStep(&TaskProcessConfig::ProcessLocalizedStartFiles);
+    AddStep(&TaskProcessConfig::ProcessBackgroundPageFile);
+    AddStep(&TaskProcessConfig::ProcessLocalizedIcons);
+    AddStep(&TaskProcessConfig::ProcessWidgetInstalledPath);
+    AddStep(&TaskProcessConfig::ProcessAppControlInfo);
+    AddStep(&TaskProcessConfig::ProcessSecurityModel);
+#ifdef DBOX_ENABLED
+    AddStep(&TaskProcessConfig::StepVerifyFeatures);
+#endif
+    AddStep(&TaskProcessConfig::StepVerifyLivebox);
+    AddStep(&TaskProcessConfig::StepCheckMinVersionInfo);
+    AddStep(&TaskProcessConfig::EndStep);
+}
+
+void TaskProcessConfig::StepFillWidgetConfig()
+{
+    if (!fillWidgetConfig(m_installContext.widgetConfig,
+                         m_installContext.widgetConfig.configInfo))
+    {
+        _E("Widget configuration is illformed");
+        ThrowMsg(Exception::ConfigParseFailed, "Widget configuration is illformed");
+    }
+}
+
+void TaskProcessConfig::ReadLocaleFolders()
+{
+    _D("Reading locale");
+    //Adding default locale
+    m_localeFolders.insert(L"");
+
+    std::string localePath =
+        m_installContext.locations->getSourceDir() + "/locales";
+
+    DIR* localeDir = opendir(localePath.c_str());
+    if (!localeDir) {
+        _D("No /locales directory in the widget package.");
+        return;
+    }
+
+    struct stat statStruct;
+    struct dirent dirent;
+    struct dirent *result;
+    int return_code;
+    errno = 0;
+    for (return_code = readdir_r(localeDir, &dirent, &result);
+            result != NULL && return_code == 0;
+            return_code = readdir_r(localeDir, &dirent, &result))
+    {
+        DPL::String dirName = DPL::FromUTF8String(dirent.d_name);
+        std::string absoluteDirName = localePath + "/";
+        absoluteDirName += dirent.d_name;
+
+        if (stat(absoluteDirName.c_str(), &statStruct) != 0) {
+            _E("stat() failed with %s", DPL::GetErrnoString().c_str());
+            continue;
+        }
+
+        if (S_ISDIR(statStruct.st_mode)) {
+            //Yes, we ignore current, parent & hidden directories
+            if (dirName[0] != L'.') {
+                _D("Adding locale directory \"%ls\"", dirName.c_str());
+                m_localeFolders.insert(dirName);
+            }
+        }
+    }
+
+    if (return_code != 0 || errno != 0) {
+        _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
+    }
+
+    if (-1 == closedir(localeDir)) {
+        _E("Failed to close dir: %s with error: %s", localePath.c_str(), DPL::GetErrnoString().c_str());
+    }
+
+    m_installContext.job->UpdateProgress(InstallerContext::INSTALL_WIDGET_CONFIG1, "Read locale folders");
+}
+
+void TaskProcessConfig::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: 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::InvalidStartFile,
+             "The Widget has no valid start file");
+}
+
+void TaskProcessConfig::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.locations->getSourceDir()) + L"/" +
+                relativePath;
+            _D("absolutePath : %ls", absolutePath.c_str());
+
+            // get property data from packaged app
+            if (WrtUtilFileExists(DPL::ToUTF8String(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.webAppType == APP_TYPE_TIZENWEBAPP
+                )
+                {
+                    std::string startPath = DPL::ToUTF8String(
+                            startFileData.path);
+
+                    if (strstr(startPath.c_str(),
+                               "http") == startPath.c_str())
+                    {
+                        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 TaskProcessConfig::ProcessBackgroundPageFile()
+{
+    if (!!m_installContext.widgetConfig.configInfo.backgroundPage) {
+        // check whether file exists
+        DPL::String backgroundPagePath = DPL::FromUTF8String(
+                m_installContext.locations->getSourceDir()) + L"/" +
+            *m_installContext.widgetConfig.configInfo.backgroundPage;
+        //if no then cancel installation
+        if (!WrtUtilFileExists(DPL::ToUTF8String(backgroundPagePath))) {
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid,
+                     L"Given background page file not found in archive");
+        }
+    }
+}
+
+void TaskProcessConfig::ProcessLocalizedIcons()
+{
+    using namespace WrtDB;
+    FOREACH(i, m_installContext.widgetConfig.configInfo.iconsList)
+    {
+        ProcessIcon(*i);
+    }
+    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"));
+}
+
+void TaskProcessConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon)
+{
+    _D("enter");
+    bool isAnyIconValid = 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;
+
+    std::set<DPL::String> &checkDuplication = icon.isSmall ? m_processedSmallIconSet : m_processedIconSet;
+
+    if (checkDuplication.count(icon.src) > 0) {
+        _D("duplication %ls ", icon.src.c_str());
+        return;
+    }
+    checkDuplication.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.locations->getSourceDir()) + L"/" +
+            relativePath;
+
+        if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) {
+            DPL::String type = MimeTypeUtils::identifyFileMimeType(absolutePath);
+
+            if (MimeTypeUtils::isMimeTypeSupportedForIcon(type)) {
+                isAnyIconValid = true;
+                localesAvailableForIcon.insert(*i);
+                _D("Icon absolutePath: %ls, assigned locale: %ls, type: %ls",
+                    absolutePath.c_str(), (*i).c_str(), type.c_str());
+            }
+        }
+    }
+
+    if (isAnyIconValid) {
+        WidgetRegisterInfo::LocalizedIcon localizedIcon(icon,
+                                                        localesAvailableForIcon);
+        m_installContext.widgetConfig.localizationData.icons.push_back(
+            localizedIcon);
+    }
+}
+
+void TaskProcessConfig::ProcessWidgetInstalledPath()
+{
+    _D("ProcessWidgetInstalledPath");
+    m_installContext.widgetConfig.widgetInstalledPath =
+        DPL::FromUTF8String(
+            m_installContext.locations->getPackageInstallationDir());
+}
+
+void TaskProcessConfig::ProcessAppControlInfo()
+{
+    _D("ProcessAppControlInfo");
+    using namespace WrtDB;
+
+    // In case of dispostion is inline, set the seperate execute
+    int index = 1;
+    // 0 index is reserved by default execute
+    FOREACH(it, m_installContext.widgetConfig.configInfo.appControlList) {
+        if (it->m_disposition ==
+            ConfigParserData::AppControlInfo::Disposition::INLINE)
+        {
+            it->m_index = index++;
+        } else {
+            it->m_index = 0;
+        }
+    }
+}
+
+void TaskProcessConfig::ProcessSecurityModel()
+{
+    // 0104.  If the "required_version" specified in the Web Application's
+    // configuration is 2.2 or higher and if the Web Application's
+    // configuration is "CSP-compatible configuration", then the WRT MUST be
+    // set to "CSP-based security mode". Otherwise, the WRT MUST be set to
+    // "WARP-based security mode".
+    // 0105.  A Web Application configuration is "CSP-compatible configuration"
+    // if the configuration includes one or more of
+    // <tizen:content-security-policy> /
+    // <tizen:content-security-policy-report-only> /
+    // <tizen:allow-navigation> elements.
+
+    bool isSecurityModelV1 = false;
+    bool isSecurityModelV2 = false;
+    WrtDB::ConfigParserData &data = m_installContext.widgetConfig.configInfo;
+
+    if (!!data.cspPolicy ||
+        !!data.cspPolicyReportOnly ||
+        !data.allowNavigationInfoList.empty())
+    {
+        data.accessInfoSet.clear();
+    }
+
+    // WARP is V1
+    if (!data.accessInfoSet.empty()) {
+        isSecurityModelV1 = true;
+    }
+
+    // CSP & allow-navigation is V2
+    if (!!data.cspPolicy ||
+        !!data.cspPolicyReportOnly ||
+        !data.allowNavigationInfoList.empty())
+    {
+        isSecurityModelV2 = true;
+    }
+
+    if (isSecurityModelV1 && isSecurityModelV2) {
+        _E("Security model is conflict");
+        ThrowMsg(Exceptions::NotAllowed, "Security model is conflict");
+    } else if (isSecurityModelV1) {
+        data.securityModelVersion =
+            WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
+    } else if (isSecurityModelV2) {
+        data.securityModelVersion =
+            WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V2;
+    } else {
+        data.securityModelVersion =
+            WrtDB::ConfigParserData::SecurityModelVersion::SECURITY_MODEL_V1;
+    }
+
+    m_installContext.job->UpdateProgress(
+        InstallerContext::INSTALL_WIDGET_CONFIG2,
+        "Finished process security model");
+}
+
+void TaskProcessConfig::StepCheckMinVersionInfo()
+{
+    if (!isMinVersionCompatible(
+            m_installContext.widgetConfig.webAppType.appType,
+            m_installContext.widgetConfig.minVersion))
+    {
+        _E("Platform version lower than required -> cancelling installation");
+        ThrowMsg(Exceptions::NotAllowed,
+                 "Platform version does not meet requirements");
+    }
+
+    m_installContext.job->UpdateProgress(
+        InstallerContext::INSTALL_WIDGET_CONFIG2,
+        "Check MinVersion Finished");
+}
+
+void TaskProcessConfig::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.webAppType.appType,
+                              it->name))
+        {
+            _D("This application type not allowed to use this feature");
+            ThrowMsg(
+                Exceptions::WidgetConfigFileInvalid,
+                "This app type [" <<
+                m_installContext.widgetConfig.webAppType.getApptypeToString()
+                                  <<
+                "] cannot be allowed to use [" <<
+                DPL::ToUTF8String(it->name) + "] feature");
+        } else {
+            newList.insert(*it);
+            featureInfo += DPL::ToUTF8String(it->name);
+            featureInfo += DPL::ToUTF8String(BR);
+        }
+    }
+    if (!data.accessInfoSet.empty()) {
+        featureInfo += WINDGET_INSTALL_NETWORK_ACCESS;
+        featureInfo += DPL::ToUTF8String(BR);
+    }
+    data.featuresList = newList;
+
+    m_installContext.job->UpdateProgress(
+        InstallerContext::INSTALL_WIDGET_CONFIG2,
+        "Widget Config step2 Finished");
+}
+
+#ifdef DBOX_ENABLED
+void TaskProcessConfig::StepVerifyLivebox()
+{
+    using namespace WrtDB;
+    ConfigParserData &data = m_installContext.widgetConfig.configInfo;
+    ConfigParserData::LiveboxList liveBoxList = data.m_livebox;
+
+    if (liveBoxList.size() <= 0) {
+        return;
+    }
+
+    FOREACH (it, liveBoxList) {
+        std::string boxType;
+
+        size_t found = (**it).m_liveboxId.find_last_of(L".");
+        if (found != std::string::npos) {
+            if (0 != (**it).m_liveboxId.compare(0, found,
+                        m_installContext.widgetConfig.tzAppid)) {
+                _E("Invalid app-widget id (doesn't begin with application id)");
+                ThrowMsg(Exceptions::WidgetConfigFileInvalid,
+                        "Invalid app-widget id(doesn't begin with application id)");
+            }
+        }
+
+        if ((**it).m_type.empty()) {
+            boxType = web_provider_livebox_get_default_type();
+        } else {
+            boxType = DPL::ToUTF8String((**it).m_type);
+        }
+
+        _D("livebox type: %s", boxType.c_str());
+
+        ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList =
+            (**it).m_boxInfo.m_boxSize;
+        char** boxSize = static_cast<char**>(
+            malloc(sizeof(char*)* boxSizeList.size()));
+
+        int boxSizeCnt = 0;
+        FOREACH (m, boxSizeList) {
+            boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).m_size).c_str());
+        }
+
+        bool chkSize = web_provider_plugin_check_supported_size(
+            boxType.c_str(), boxSize, boxSizeCnt);
+
+        for(int i = 0; i < boxSizeCnt; i++) {
+            free(boxSize[i]);
+        }
+        free(boxSize);
+
+        if(!chkSize) {
+            _E("Invalid boxSize");
+            ThrowMsg(Exceptions::WidgetConfigFileInvalid, "Invalid boxSize");
+        }
+    }
+}
+#endif
+
+bool TaskProcessConfig::isFeatureAllowed(WrtDB::AppType appType,
+                                        DPL::String featureName)
+{
+    using namespace WrtDB;
+    _D("AppType = [%s]", WidgetType(appType).getApptypeToString().c_str());
+    _D("FetureName = [%ls]", featureName.c_str());
+
+    AppType featureType = APP_TYPE_UNKNOWN;
+    std::string featureStr = DPL::ToUTF8String(featureName);
+    const char* feature = featureStr.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::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;
+}
+
+bool TaskProcessConfig::parseVersionString(const std::string &version,
+                                          long &majorVersion,
+                                          long &minorVersion,
+                                          long &microVersion) const
+{
+    std::istringstream inputString(version);
+    inputString >> majorVersion;
+    if (inputString.bad() || inputString.fail()) {
+        _W("Invalid minVersion format.");
+        return false;
+    }
+    inputString.get(); // skip period
+    inputString >> minorVersion;
+    if (inputString.bad() || inputString.fail()) {
+        _W("Invalid minVersion format");
+        return false;
+    } else {
+        inputString.get(); // skip period
+        if (inputString.bad() || inputString.fail()) {
+            inputString >> microVersion;
+        }
+    }
+    return true;
+}
+
+bool TaskProcessConfig::isMinVersionCompatible(
+    WrtDB::AppType appType,
+    const DPL::OptionalString &
+    widgetVersion) const
+{
+    if (!widgetVersion || (*widgetVersion).empty()) {
+        if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP
+            ) {
+            return false;
+        } else {
+            _W("minVersion attribute is empty. WRT assumes platform "
+               "supports this widget.");
+            return true;
+        }
+    }
+
+    //Parse widget version
+    long majorWidget = 0, minorWidget = 0, microWidget = 0;
+    if (!parseVersionString(DPL::ToUTF8String(*widgetVersion), majorWidget,
+                            minorWidget, microWidget))
+    {
+        _W("Invalid format of widget version string.");
+        return false;
+    }
+
+    //Parse supported version
+    long majorSupported = 0, minorSupported = 0, microSupported = 0;
+    std::string version;
+    if (appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP
+        ) {
+        version = WrtDB::GlobalConfig::GetTizenVersion();
+    } else {
+        _W("Invaild AppType");
+        return false;
+    }
+
+    if (!parseVersionString(version,
+                            majorSupported, minorSupported, microSupported))
+    {
+        _W("Invalid format of platform version string.");
+        return true;
+    }
+
+    if (majorWidget > majorSupported ||
+        (majorWidget == majorSupported && minorWidget > minorSupported))
+    {
+        _D("Platform doesn't support this widget.");
+        return false;
+    }
+    return true;
+}
+
+bool TaskProcessConfig::isTizenWebApp() const
+{
+    if (m_installContext.widgetConfig.webAppType.appType == WrtDB::AppType::APP_TYPE_TIZENWEBAPP)
+    {
+        return true;
+    }
+    return false;
+}
+
+bool TaskProcessConfig::fillWidgetConfig(
+    WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
+    WrtDB::ConfigParserData& configInfo)
+{
+    pWidgetConfigInfo.guid = configInfo.widget_id;
+
+    if (!!configInfo.version) {
+        if (!pWidgetConfigInfo.version) {
+            pWidgetConfigInfo.version = configInfo.version;
+        } else {
+            if (pWidgetConfigInfo.version != configInfo.version) {
+                _E("Invalid archive");
+                return false;
+            }
+        }
+    }
+    if (!!configInfo.minVersionRequired) {
+        pWidgetConfigInfo.minVersion = configInfo.minVersionRequired;
+    } else if (!!configInfo.tizenMinVersionRequired) {
+        pWidgetConfigInfo.minVersion = configInfo.tizenMinVersionRequired;
+    }
+    return true;
+}
+
+void TaskProcessConfig::StartStep()
+{
+    LOGD("--------- <TaskProcessConfig> : START ----------");
+}
+
+void TaskProcessConfig::EndStep()
+{
+    LOGD("--------- <TaskProcessConfig> : END ----------");
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_process_config.h b/src_wearable/jobs/widget_install/task_process_config.h
new file mode 100755 (executable)
index 0000000..fa20264
--- /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.
+ */
+/*
+ * @file    task_process_config.h
+ * @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_PROCESS_CONFIG_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PROCESS_CONFIG_H
+
+#include <set>
+#include <list>
+
+#include <dpl/task.h>
+#include <dpl/string.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <wrt_common_types.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+class TaskProcessConfig :
+    public DPL::TaskDecl<TaskProcessConfig>
+{
+  private:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ConfigParseFailed)
+    };
+
+    typedef std::list<std::pair<DPL::String, DPL::String> > StringPairList;
+
+    InstallerContext& m_installContext;
+    WrtDB::LocaleSet m_localeFolders;
+    std::set<DPL::String> m_processedIconSet;
+    std::set<DPL::String> m_processedSmallIconSet;
+
+    void StepFillWidgetConfig();
+    void ReadLocaleFolders();
+    void ProcessLocalizedStartFiles();
+    void ProcessStartFile(
+        const DPL::OptionalString& path,
+        const DPL::OptionalString& type,
+        const DPL::OptionalString& encoding =
+            DPL::OptionalString(),
+        bool typeForcedInConfig = false);
+    void ProcessBackgroundPageFile();
+    void ProcessLocalizedIcons();
+    void ProcessIcon(const WrtDB::ConfigParserData::Icon& icon);
+    void ProcessWidgetInstalledPath();
+    void ProcessAppControlInfo();
+    void ProcessSecurityModel();
+    void StepVerifyFeatures();
+    void StepVerifyLivebox();
+    void StepCheckMinVersionInfo();
+
+    template <typename Ex, const char* Msg>
+    void StepCancelInstallation();
+
+    void StartStep();
+    void EndStep();
+
+    DPL::String createAuthorWidgetInfo() const;
+    bool isFeatureAllowed(
+        WrtDB::AppType appType, DPL::String featureName);
+    bool isMinVersionCompatible(
+        WrtDB::AppType appType,
+        const DPL::OptionalString &widgetVersion) const;
+    /**
+     * @brief Parses version string in format "major.minor.micro anything"
+     * Returns false if format is invalid
+     */
+    bool isTizenWebApp() const;
+    bool parseVersionString(const std::string &version, long &majorVersion,
+                            long &minorVersion, long &microVersion) const;
+
+    bool fillWidgetConfig(WrtDB::WidgetRegisterInfo& pWidgetConfigInfo,
+                          WrtDB::ConfigParserData& configInfo);
+
+  public:
+    TaskProcessConfig(InstallerContext& installTaskContext);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PROCESS_CONFIG_H
diff --git a/src_wearable/jobs/widget_install/task_recovery.cpp b/src_wearable/jobs/widget_install/task_recovery.cpp
new file mode 100644 (file)
index 0000000..fb2b72a
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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_recovery.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task recovery
+ */
+#include "task_recovery.h"
+
+#include <dpl/log/log.h>
+#include <dpl/errno_string.h>
+#include <dpl/foreach.h>
+
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <ace_api_install.h>
+#include <ace_registration.h>
+#include <ace-common/ace_api_common.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const std::string BACKUP_ID = ".backup";
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskRecovery::TaskRecovery(InstallerContext& context) :
+    DPL::TaskDecl<TaskRecovery>(this),
+    m_context(context)
+{
+    AddStep(&TaskRecovery::StartStep);
+    AddStep(&TaskRecovery::StepRecoveryDirectory);
+    AddStep(&TaskRecovery::StepRecoveryDatabase);
+    AddStep(&TaskRecovery::EndStep);
+}
+
+void TaskRecovery::StepRecoveryDirectory()
+{
+    _D("StepRecoveryDirectory ...");
+    // check backup folder
+    DPL::Utils::Path installedPath(WrtDB::GlobalConfig::GetUserInstalledWidgetPath());
+    installedPath /= m_context.widgetConfig.tzPkgid;
+
+    DPL::Utils::Path backupPath(WrtDB::GlobalConfig::GetUserInstalledWidgetPath());
+    backupPath /= DPL::ToUTF8String(m_context.widgetConfig.tzPkgid) + BACKUP_ID;
+
+    _D("installedPath : %s", installedPath.Fullpath().c_str());
+    _D("backupPath : %s", backupPath.Fullpath().c_str());
+
+    if (backupPath.Exists()) {
+        DPL::Utils::TryRemove(installedPath);
+
+        DPL::Utils::Rename(backupPath, installedPath);
+    } else {
+        ThrowMsg(Exceptions::RecoveryFailed, "backup folder doesn't exist");
+    }
+}
+
+void TaskRecovery::StepRecoveryDatabase()
+{
+    _D("StepRecoveryDatabase ... %s", m_context.widgetConfig.tzPkgid.c_str());
+    Try {
+        std::string backupId, deleteId;
+
+        TizenAppId dbAppId = WidgetDAOReadOnly::getTizenAppId(m_context.widgetConfig.tzPkgid);
+        _D("Get appid : %ls", dbAppId.c_str());
+        std::string appId = DPL::ToUTF8String(dbAppId);
+
+        if (0 == appId.compare(appId.size() - BACKUP_ID.length(), BACKUP_ID.length(), BACKUP_ID)) {
+            backupId = appId;
+            deleteId = backupId.substr(0, backupId.length() -
+                    BACKUP_ID.length());
+        } else {
+            backupId = appId + BACKUP_ID;
+            deleteId = appId;
+        }
+
+        if (WrtDB::WidgetDAOReadOnly::isWidgetInstalled(DPL::FromUTF8String(backupId))) {
+            _D("Recovery Database...");
+            _D("backupId %s " , backupId.c_str());
+            _D("deleteId %s " , deleteId.c_str());
+
+            // remove ace
+            ace_unregister_widget(static_cast<ace_widget_handle_t>(
+                        WidgetDAOReadOnly::getHandle(DPL::
+                            FromUTF8String(deleteId))));
+            ace_unregister_widget(static_cast<ace_widget_handle_t>(
+                        WidgetDAOReadOnly::getHandle(DPL::
+                            FromUTF8String(backupId))));
+
+            WidgetDAO::unregisterWidget(DPL::FromUTF8String(deleteId));
+            WidgetDAO::updateTizenAppId(DPL::FromUTF8String(backupId),
+                    DPL::FromUTF8String(deleteId));
+
+            if(!AceApi::registerAceWidgetFromDB(WidgetDAOReadOnly::getHandle(
+                            DPL::FromUTF8String(deleteId)))) {
+                _E("ace database restore failed");
+            }
+        }
+
+        WidgetDAOReadOnly dao(DPL::FromUTF8String(deleteId));
+        m_context.requestedPath =
+            DPL::ToUTF8String(*dao.getWidgetInstalledPath());
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+    {
+        ThrowMsg(Exceptions::RecoveryFailed, "[WidgetNotExist] Failure in recovery db");
+    }
+    Catch(WidgetDAO::Exception::DatabaseError)
+    {
+        ThrowMsg(Exceptions::RecoveryFailed, "[DatabaseError] Failure in recovery db");
+    }
+}
+
+void TaskRecovery::StartStep()
+{
+    LOGD("--------- <TaskRecovery> : START ----------");
+}
+
+void TaskRecovery::EndStep()
+{
+    LOGD("--------- <TaskRecovery> : END ----------");
+}
+} //namespace RecoveryInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_recovery.h b/src_wearable/jobs/widget_install/task_recovery.h
new file mode 100644 (file)
index 0000000..92a9d79
--- /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       task_recovery.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_RECOVERY_FILES_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_RECOVERY_FILES_H_
+
+#include <dpl/task.h>
+#include <dpl/string.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskRecovery : public DPL::TaskDecl<TaskRecovery>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StartStep();
+    void EndStep();
+    void StepRecoveryDirectory();
+    void StepRecoveryDatabase();
+
+  public:
+    explicit TaskRecovery(InstallerContext &context);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_RECOVERY_FILES_H_ */
diff --git a/src_wearable/jobs/widget_install/task_remove_backup.cpp b/src_wearable/jobs/widget_install/task_remove_backup.cpp
new file mode 100755 (executable)
index 0000000..d691041
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * 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_backup.cpp
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task backup files remove
+ */
+#include <widget_install/task_remove_backup.h>
+
+#include <sys/stat.h>
+#include <string>
+#include <sstream>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/foreach.h>
+#include <dpl/assert.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
+#include <ace_api_install.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskRemoveBackupFiles::TaskRemoveBackupFiles(InstallerContext& context) :
+    DPL::TaskDecl<TaskRemoveBackupFiles>(this),
+    m_context(context)
+{
+    AddStep(&TaskRemoveBackupFiles::StartStep);
+    if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
+    {
+        AddStep(&TaskRemoveBackupFiles::StepRemoveBackupFiles);
+    }
+    AddStep(&TaskRemoveBackupFiles::StepDeleteBackupDB);
+    AddStep(&TaskRemoveBackupFiles::StepDeleteBackupWidgetInterfaceDB);
+    AddStep(&TaskRemoveBackupFiles::EndStep);
+}
+
+void TaskRemoveBackupFiles::StepRemoveBackupFiles()
+{
+    std::ostringstream backupDir;
+    backupDir << m_context.locations->getBackupDir();
+
+    if (WrtUtilRemove(backupDir.str())) {
+        _D("Success to remove backup files : %s", backupDir.str().c_str());
+    } else {
+        _E("Failed to remove backup directory : %s", backupDir.str().c_str());
+        ThrowMsg(Exceptions::RemoveBackupFailed,
+                 "Error occurs during removing existing folder");
+    }
+
+    std::string tmp = m_context.locations->getTemporaryPackageDir();
+    if (WrtUtilRemove(tmp)) {
+        _D("Success to remove temp directory : %s", tmp.c_str());
+    } else {
+        _E("Failed to remove temp directory : %s", tmp.c_str());
+    }
+}
+
+void TaskRemoveBackupFiles::StepDeleteBackupDB()
+{
+    _D("StepDeleteBackupDB");
+    std::list<TizenAppId> idList = WidgetDAOReadOnly::getTzAppIdList(m_context.widgetConfig.tzPkgid);
+    FOREACH(it, idList){
+        Try
+        {
+            DPL::String suffix = L".backup";
+            if( it->size() >= suffix.size() && it->compare(it->size() - suffix.size() , suffix.size(), suffix) == 0)
+                WidgetDAO::unregisterWidget(*it);
+        }
+        Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+        {
+            _E("Fail to delete old version db information");
+        }
+    }
+}
+
+void TaskRemoveBackupFiles::StepDeleteBackupWidgetInterfaceDB()
+{
+    _D("StepDeleteBackupWidgetInterfaceDB");
+    using namespace WidgetInterfaceDB;
+    using namespace WrtDB;
+
+    DbWidgetHandle handle =
+        WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+    std::string backupDbPath = WidgetInterfaceDAO::databaseFileName(handle);
+    backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
+
+    // remove backup database
+    if (remove(backupDbPath.c_str()) != 0) {
+        _W("Fail to remove");
+    }
+}
+
+void TaskRemoveBackupFiles::StartStep()
+{
+    LOGD("--------- <TaskRemoveBackupFiles> : START ----------");
+}
+
+void TaskRemoveBackupFiles::EndStep()
+{
+    LOGD("--------- <TaskRemoveBackupFiles> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_remove_backup.h b/src_wearable/jobs/widget_install/task_remove_backup.h
new file mode 100644 (file)
index 0000000..1dcdf5b
--- /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_remove_backup.h
+ * @author  Soyoung kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task backup files remove
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_REMOVE_BACKUP_FILES_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_REMOVE_BACKUP_FILES_H
+
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskRemoveBackupFiles :
+    public DPL::TaskDecl<TaskRemoveBackupFiles>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StepRemoveBackupFiles();
+    void StepDeleteBackupDB();
+    void StepDeleteBackupWidgetInterfaceDB();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskRemoveBackupFiles(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_REMOVE_BACKUP_FILES_H
diff --git a/src_wearable/jobs/widget_install/task_smack.cpp b/src_wearable/jobs/widget_install/task_smack.cpp
new file mode 100644 (file)
index 0000000..5076d14
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * 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/wrt-dao-ro/common_dao_types.h>
+#include <dpl/foreach.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/utils/bash_utils.h>
+#include <dpl/utils/path.h>
+#include <vcore/Certificate.h>
+#include <vcore/CryptoHash.h>
+#include <vcore/SignatureFinder.h>
+#include <privilege-control.h>
+#include <sys/smack.h>
+#include <sstream>
+#include <installer_log.h>
+#include <privilege-control.h>
+
+using namespace WrtDB;
+using namespace ValidationCore;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+void freeList(const char** list) {
+    for (int i = 0; list[i] != NULL; i++)
+    {
+        delete(list[i]);
+    }
+    delete[] list;
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskSmack::TaskSmack(InstallerContext& context) :
+    DPL::TaskDecl<TaskSmack>(this),
+    m_context(context)
+{
+    AddStep(&TaskSmack::StartStep);
+    AddStep(&TaskSmack::StepSetInstall);
+    AddStep(&TaskSmack::StepSmackFolderLabeling);
+    AddStep(&TaskSmack::StepSmackPrivilege);
+    AddStep(&TaskSmack::StepAddLabelNPRuntime);
+    AddStep(&TaskSmack::StepLabelSignatureFiles);
+    AddStep(&TaskSmack::EndStep);
+
+    AddAbortStep(&TaskSmack::StepAbortSmack);
+}
+
+void TaskSmack::StepSetInstall()
+{
+    _D("----------------> SMACK: StepStartSetSmack()");
+
+    m_pkgId = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+
+    if (PC_OPERATION_SUCCESS != perm_app_install(m_pkgId.c_str())) {
+        ThrowMsg(Exceptions::NotAllowed, "Instalation failure. "
+                "failure in creating smack rules file.");
+    }
+}
+
+void TaskSmack::StepSmackFolderLabeling()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::SmackFolderLabelingStep()");
+
+    /* /opt/usr/apps/[pkgid] directory's label is "_" */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
+                m_context.locations->getPackageInstallationDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        _W("Add label to %s", m_context.locations->getPackageInstallationDir().c_str());
+    }
+
+    /* for prelaod */
+    if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD) {
+        if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
+                    m_context.locations->getUserDataRootDir().c_str(),
+                    APP_PATH_ANY_LABEL, "_")) {
+        }
+    }
+
+    /* res directory */
+    std::string resDir = m_context.locations->getPackageInstallationDir() +
+        "/res";
+
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(), resDir.c_str(),
+                APP_PATH_PRIVATE)) {
+        _W("Add label to %s", resDir.c_str());
+    }
+
+    /* data directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
+                m_context.locations->getPrivateStorageDir().c_str(),
+                APP_PATH_PRIVATE)) {
+        _W("Add label to %s", m_context.locations->getPrivateStorageDir().c_str());
+    }
+
+    /* tmp directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
+                m_context.locations->getPrivateTempStorageDir().c_str(),
+                APP_PATH_PRIVATE))
+    {
+        _W("Add label to %s", m_context.locations->getPrivateTempStorageDir().c_str());
+    }
+
+    /* bin directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
+                m_context.locations->getBinaryDir().c_str(),
+                APP_PATH_PRIVATE)) {
+        _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
+    }
+
+    if(!setLabelForSharedDir(m_pkgId.c_str())) {
+        _W("Add label to shared directory");
+    }
+
+    /* TODO : set label at wrt-client */
+}
+
+void TaskSmack::StepSmackPrivilege()
+{
+    _D("----------------> SMACK:\
+        Jobs::WidgetInstall::TaskSmack::SmackPrivilegeStep()");
+
+    std::string id = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+    char* appId = NULL;
+    appId = (char*)calloc(1, id.length() + 1);
+    snprintf(appId, id.length() + 1, "%s", id.c_str());
+
+    WrtDB::ConfigParserData::PrivilegeList privileges =
+        m_context.widgetConfig.configInfo.privilegeList;
+
+    char** perm_list = new char*[privileges.size() + 1];
+    int index = 0;
+    FOREACH(it, privileges) {
+        _D("Permission : %ls", it->name.c_str());
+        int length = DPL::ToUTF8String(it->name).length();
+        char *priv = new char[length + 1];
+        snprintf(priv, length + 1, "%s",
+                 DPL::ToUTF8String(it->name).c_str());
+        perm_list[index++] = priv;
+    }
+    perm_list[index] = NULL;
+
+    if (PC_OPERATION_SUCCESS != perm_app_enable_permissions(appId, APP_TYPE_WGT,
+                const_cast<const char **>(perm_list), true)) {
+        _W("failure in contructing smack rules based on perm_list");
+    }
+
+    free(appId);
+    index = 0;
+    while (NULL != perm_list[index]) {
+        delete [] perm_list[index++];
+    }
+    delete [] perm_list;
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_SMACK_ENABLE,
+        "Widget SMACK Enabled");
+}
+
+void TaskSmack::StepAddLabelNPRuntime()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepAddLabelNPRuntime()");
+
+    if (0 == access(m_context.locations->getNPPluginsDir().c_str(), F_OK)) {
+        if (PC_OPERATION_SUCCESS !=
+                perm_app_setup_path(DPL::ToUTF8String(m_context.widgetConfig.tzPkgid).c_str(),
+                    m_context.locations->getNPPluginsExecFile().c_str(),
+                    PERM_APP_PATH_NPRUNTIME)) {
+            _E("failed to set smack execute label to %s",
+                    m_context.locations->getNPPluginsExecFile().c_str());
+        }
+    }
+}
+
+
+void TaskSmack::StepLabelSignatureFiles()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepLabelSignatureFiles()");
+
+    DPL::Utils::Path widgetPath{
+            m_context.locations->getPackageInstallationDir()};
+    widgetPath /= WrtDB::GlobalConfig::GetWidgetSrcPath();
+
+    SignatureFileInfoSet signatureFiles;
+    SignatureFinder signatureFinder(widgetPath.Fullpath());
+    if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) {
+        ThrowMsg(Exceptions::SignatureNotFound,
+                 "Error while discovering signature files.");
+    }
+
+    for (auto it = signatureFiles.cbegin(); it != signatureFiles.cend(); ++it) {
+        auto sigPath = widgetPath / it->getFileName();
+
+        _D("Setting label to %s", sigPath.Fullpath().c_str());
+        if (PC_OPERATION_SUCCESS != perm_app_setup_path(m_pkgId.c_str(),
+                    sigPath.Fullpath().c_str(),
+                    APP_PATH_ANY_LABEL, "_")) {
+            _W("Failed to set label to %s", sigPath.Fullpath().c_str());
+        }
+    }
+}
+
+void TaskSmack::StepRevokeForUpdate()
+{
+    _D("----------------> SMACK:\
+        Jobs::WidgetInstall::TaskSmack::StepRevokePrivilegeForUpdate()");
+
+    if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId.c_str())) {
+        _W("failure in revoking smack permissions");
+    }
+}
+
+void TaskSmack::StepAbortSmack()
+{
+    _D("----------------> SMACK:\
+            Jobs::WidgetInstall::TaskSmack::StepAbortSmack()");
+
+    if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(m_pkgId.c_str())) {
+        _W("failure in revoking smack permissions");
+    }
+
+    if (PC_OPERATION_SUCCESS != perm_app_uninstall(m_pkgId.c_str())) {
+        _W("failure in removing smack rules file");
+    }
+}
+
+bool TaskSmack::setLabelForSharedDir(const char* pkgId)
+{
+    /* /shared directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                m_context.locations->getSharedRootDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        _W("Add label to %s", m_context.locations->getUserDataRootDir().c_str());
+    }
+
+    /* /shared/res directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                m_context.locations->getSharedResourceDir().c_str(),
+                APP_PATH_ANY_LABEL, "_")) {
+        _W("Add label to %s", m_context.locations->getSharedResourceDir().c_str());
+    }
+
+    /* /shared/trusted directory */
+    CertificatePtr rootCert = m_context.widgetSecurity.getAuthorCertificatePtr();
+    if (!!rootCert) {
+        ValidationCore::Crypto::Hash::SHA1 sha1;
+        sha1.Append(rootCert->getDER());
+        sha1.Finish();
+        std::string sha1String = sha1.ToBase64String();
+        size_t iPos = sha1String.find("/");
+        while(iPos < std::string::npos) {
+            sha1String.replace(iPos, 1, "#");
+            iPos = sha1String.find("/");
+        }
+
+        _D("sha1 label string : %s", sha1String.c_str());
+
+        if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                    m_context.locations->getSharedTrustedDir().c_str(),
+                    APP_PATH_GROUP_RW, sha1String.c_str())) {
+            _W("Add label to %s", m_context.locations->getBinaryDir().c_str());
+        }
+    }
+
+    /* /shared/data directory */
+    if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgId,
+                m_context.locations->getSharedDataDir().c_str(),
+                APP_PATH_PUBLIC_RO)) {
+        _W("Add label to %s", m_context.locations->getSharedDataDir().c_str());
+    }
+
+    return true;
+}
+
+void TaskSmack::StartStep()
+{
+    LOGD("--------- <TaskSmack> : START ----------");
+    if (PC_OPERATION_SUCCESS != perm_begin()) {
+        LOGE("Failed to smack transaction begin.");
+        ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction begin");
+    }
+}
+
+void TaskSmack::EndStep()
+{
+    LOGD("--------- <TaskSmack> : END ----------");
+    if (PC_OPERATION_SUCCESS != perm_end()) {
+        LOGE("Failed to smack transaction end.");
+        ThrowMsg(Exceptions::SmackTransactionFailed, "Failed to smack transaction end");
+    }
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_smack.h b/src_wearable/jobs/widget_install/task_smack.h
new file mode 100644 (file)
index 0000000..2c7b54f
--- /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_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>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskSmack :
+    public DPL::TaskDecl<TaskSmack>
+{
+  private:
+    InstallerContext& m_context;
+    std::string m_pkgId;
+
+    void StepSetInstall();
+    void StepSmackFolderLabeling();
+    void StepSmackPrivilege();
+    void StepAddLabelNPRuntime();
+    void StepLabelSignatureFiles();
+    void StepRevokeForUpdate();
+    void StepAbortSmack();
+
+    bool setLabelForSharedDir(const char* pkgId);
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskSmack(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_SMACK_H */
diff --git a/src_wearable/jobs/widget_install/task_status_check.cpp b/src_wearable/jobs/widget_install/task_status_check.cpp
new file mode 100644 (file)
index 0000000..6a60cff
--- /dev/null
@@ -0,0 +1,159 @@
+ /*
+ * 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_status_check.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task  install osp service
+ */
+#include "task_status_check.h"
+
+#include <unistd.h>
+#include <string>
+
+#include <app_manager.h>
+#include <web_provider_service.h>
+#include <dpl/errno_string.h>
+#include <dpl/utils/bash_utils.h>
+
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskStatusCheck::TaskStatusCheck(InstallerContext& context) :
+    DPL::TaskDecl<TaskStatusCheck>(this),
+    m_context(context)
+{
+    AddStep(&TaskStatusCheck::StartStep);
+    AddStep(&TaskStatusCheck::CheckAppRunningStateStep);
+    AddStep(&TaskStatusCheck::DynamicBoxesRemoveStep);
+    AddStep(&TaskStatusCheck::EndStep);
+}
+
+void TaskStatusCheck::CheckAppRunningStateStep()
+{
+    _D("Step: CheckAppRunningStateStep");
+    std::string webAppPkgId = DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+
+    int ret = 0;
+    pkgmgrinfo_pkginfo_h handle;
+    ret = pkgmgrinfo_pkginfo_get_pkginfo(webAppPkgId.c_str(), &handle);
+    if (ret != PMINFO_R_OK) {
+        _E("Can't find [%s] in package manager", webAppPkgId.c_str());
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::GetInfoPkgMgrFailed,
+                "package id can't find from package manager");
+    }
+    ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_ALL_APP,
+            terminateRunningApp, NULL);
+    if (ret != PMINFO_R_OK) {
+        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                "widget is running");
+    }
+    pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+}
+
+int TaskStatusCheck::terminateRunningApp(pkgmgrinfo_appinfo_h handle,
+        void* /*user_data*/)
+{
+    char *appId = NULL;
+    pkgmgrinfo_appinfo_get_appid(handle, &appId);
+    _D("# Terminating App : [%s]", appId);
+
+    bool isRunning = false;
+    int ret = app_manager_is_running(appId, &isRunning);
+    if (APP_MANAGER_ERROR_NONE != ret) {
+        _E("Fail to get running state");
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                "widget is running");
+    }
+
+    if (true == isRunning) {
+        // get app_context for running application
+        // app_context must be released with app_context_destroy
+        app_context_h appCtx = NULL;
+        ret =
+            app_manager_get_app_context(appId, &appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to get app_context");
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                    "widget is running");
+        }
+
+        // terminate app_context_h
+        ret = app_manager_terminate_app(appCtx);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to terminate running application");
+            app_context_destroy(appCtx);
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                    "widget is running");
+        } else {
+            app_context_destroy(appCtx);
+            // app_manager_terminate_app isn't sync API
+            // wait until application isn't running (50ms * 100)
+            bool isStillRunning = true;
+            int checkingloop = 100;
+            struct timespec duration = { 0, 50 * 1000 * 1000 };
+            while (--checkingloop >= 0) {
+                nanosleep(&duration, NULL);
+                int ret = app_manager_is_running(appId,
+                        &isStillRunning);
+                if (APP_MANAGER_ERROR_NONE != ret) {
+                    _E("Fail to get running state");
+                    ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                            "widget is running");
+                }
+                if (!isStillRunning) {
+                    break;
+                }
+            }
+            if (isStillRunning) {
+                _E("Fail to terminate running application");
+                ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError,
+                        "widget is running");
+            }
+            _D("terminate application");
+        }
+    }
+    return 0;
+}
+
+void TaskStatusCheck::DynamicBoxesRemoveStep()
+{
+    _D("Step: DynamicBoxesRemoveStep");
+
+    // check if this webapp has dynaimc boxes, and request to remove them
+    web_provider_service_wait_boxes_removed(
+            DPL::ToUTF8String(m_context.widgetConfig.tzAppid).c_str());
+
+    _D("Finished to handle this web app's dynamic box");
+}
+
+void TaskStatusCheck::StartStep()
+{
+    LOGD("--------- <TaskStatusCheck> : START ----------");
+}
+
+void TaskStatusCheck::EndStep()
+{
+    LOGD("--------- <TaskStatusCheck> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_status_check.h b/src_wearable/jobs/widget_install/task_status_check.h
new file mode 100644 (file)
index 0000000..3ae5a95
--- /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_status_check.h
+ * @author     soyoung kim (sy037.kim@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_TASK_STATUS_CHECK_H_
+#define SRC_JOBS_WIDGET_INSTALL_TASK_STATUS_CHECK_H_
+
+#include <dpl/task.h>
+#include <string>
+#include <pkgmgr-info.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskStatusCheck : public DPL::TaskDecl<TaskStatusCheck>
+{
+  private:
+    // Installation context
+    InstallerContext &m_context;
+
+    void CheckAppRunningStateStep();
+    void DynamicBoxesRemoveStep();
+
+    void StartStep();
+    void EndStep();
+
+    static int terminateRunningApp(pkgmgrinfo_appinfo_h handle, void *user_data);
+
+  public:
+    explicit TaskStatusCheck(InstallerContext &installerContext);
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+#endif /* SRC_JOBS_WIDGET_INSTALL_TASK_STATUS_CHECK_H_ */
diff --git a/src_wearable/jobs/widget_install/task_update_files.cpp b/src_wearable/jobs/widget_install/task_update_files.cpp
new file mode 100644 (file)
index 0000000..95d5d96
--- /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.
+ */
+/*
+ * @file    task_update_files.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task update files
+ */
+
+#include <unistd.h>
+#include <utility>
+#include <vector>
+#include <string>
+#include <algorithm>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include <dpl/assert.h>
+#include <dpl/foreach.h>
+#include <dpl/utils/wrt_utility.h>
+
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/exception.h>
+#include <dpl/errno_string.h>
+
+#include <widget_install/task_update_files.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/directory_api.h>
+#include <widget_install_to_external.h>
+#include <pkgmgr/pkgmgr_parser.h>
+
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+inline const char* GetWidgetBackupDirPath()
+{
+    return "backup";
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskUpdateFiles::TaskUpdateFiles(InstallerContext& context) :
+    DPL::TaskDecl<TaskUpdateFiles>(this),
+    m_context(context)
+{
+    AddStep(&TaskUpdateFiles::StartStep);
+    AddStep(&TaskUpdateFiles::StepBackupDirectory);
+    AddStep(&TaskUpdateFiles::EndStep);
+
+    AddAbortStep(&TaskUpdateFiles::StepAbortBackupDirectory);
+}
+
+void TaskUpdateFiles::StepBackupDirectory()
+{
+    _D("StepCreateBackupFolder");
+
+    Try {
+        std::string pkgid =
+            DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
+        if (APP2EXT_SD_CARD == app2ext_get_app_location(pkgid.c_str())) {
+            _D("Installed external directory");
+            WidgetInstallToExtSingleton::Instance().initialize(pkgid);
+            WidgetInstallToExtSingleton::Instance().disable();
+        }
+    } Catch(WidgetInstallToExt::Exception::ErrorInstallToExt) {
+        _E("Failed disable app2sd");
+        ReThrowMsg(Exceptions::BackupFailed, "Error occurs during disable app2sd");
+    }
+
+    std::string backPath = m_context.locations->getBackupDir();
+    _D("Backup resource directory path : %s", backPath.c_str());
+    std::string pkgPath = m_context.locations->getPackageInstallationDir();
+
+    if (0 == access(backPath.c_str(), F_OK)) {
+        if (!WrtUtilRemove(backPath)) {
+            ThrowMsg(Exceptions::RemovingFolderFailure,
+                    "Error occurs during removing backup resource directory");
+        }
+    }
+    _D("copy : %s to %s", pkgPath.c_str(), backPath.c_str());
+    if ((rename(pkgPath.c_str(), backPath.c_str())) != 0) {
+        _E("Failed to rename %s to %s", pkgPath.c_str(), backPath.c_str());
+        ThrowMsg(Exceptions::BackupFailed,
+                "Error occurs during rename file");
+    }
+
+    WrtUtilMakeDir(pkgPath);
+}
+
+void TaskUpdateFiles::StepAbortBackupDirectory()
+{
+    _D("StepAbortCopyFiles");
+
+    std::string backPath = m_context.locations->getBackupDir();
+    std::string pkgPath = m_context.locations->getPackageInstallationDir();
+
+    _D("Backup Folder %s to %s", backPath.c_str(), pkgPath.c_str());
+
+    if (!WrtUtilRemove(pkgPath)) {
+        _E("Failed to remove %s", pkgPath.c_str());
+    }
+
+    if (rename(backPath.c_str(), pkgPath.c_str()) != 0) {
+        _E("Failed to rename %s to %s", backPath.c_str(), pkgPath.c_str());
+    }
+}
+
+void TaskUpdateFiles::StartStep()
+{
+    LOGD("--------- <TaskUpdateFiles> : START ----------");
+}
+
+void TaskUpdateFiles::EndStep()
+{
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_CREATE_BACKUP_DIR,
+        "Backup directory created for update");
+
+    LOGD("--------- <TaskUpdateFiles> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_update_files.h b/src_wearable/jobs/widget_install/task_update_files.h
new file mode 100644 (file)
index 0000000..1d02e0e
--- /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    task_update_files.h
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for installer task update files
+ */
+#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UPDATE_FILES_H
+#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UPDATE_FILES_H
+
+#include <set>
+#include <dpl/task.h>
+#include <dpl/string.h>
+
+class InstallerContext;
+
+namespace {
+typedef std::set<std::string> ExistFileList;
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskUpdateFiles :
+    public DPL::TaskDecl<TaskUpdateFiles>
+{
+  private:
+    InstallerContext& m_context;
+
+    void StepBackupDirectory();
+
+    void StepAbortBackupDirectory();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskUpdateFiles(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_UPDATE_FILES_H */
diff --git a/src_wearable/jobs/widget_install/task_user_data_manipulation.cpp b/src_wearable/jobs/widget_install/task_user_data_manipulation.cpp
new file mode 100644 (file)
index 0000000..43f29c3
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * 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_user_data_manipulation.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task user data folder 
+ */
+#include <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <widget_install/task_user_data_manipulation.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/directory_api.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/assert.h>
+#include <dpl/errno_string.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <string>
+#include <installer_log.h>
+
+#define WEBAPP_DEFAULT_UID  5000
+#define WEBAPP_DEFAULT_GID  5000
+
+namespace {
+const mode_t PRIVATE_STORAGE_MODE = 0700;
+const mode_t SHARED_STORAGE_MODE = 0755;
+}
+
+using namespace WrtDB;
+
+namespace {
+void changeOwnerForDirectory(std::string storagePath, mode_t mode) {
+    if (euidaccess(storagePath.c_str(), F_OK) != 0) {
+        if (!WrtUtilMakeDir(storagePath, mode)) {
+            _E("Failed to create directory : %s", storagePath.c_str());
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "Failed to create directory : " << storagePath);
+        }
+        // '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.c_str(),
+                  WEBAPP_DEFAULT_UID,
+                  WEBAPP_DEFAULT_GID) != 0)
+        {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "Chown to invaild user");
+        }
+    } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) {
+        _D("%s already exists.", storagePath.c_str());
+        // Even if private directory already is created, private dircetory
+        // should change owner (recursively).
+        if (chown(storagePath.c_str(),
+                  WEBAPP_DEFAULT_UID,
+                  WEBAPP_DEFAULT_GID) != 0)
+        {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "Chown to invaild user");
+        }
+        if (chmod(storagePath.c_str(), mode) != 0) {
+            ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                     "chmod to 0700");
+        }
+    } else {
+        ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed,
+                 "No access to private storage.");
+    }
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+TaskUserDataManipulation::TaskUserDataManipulation(InstallerContext& context) :
+    DPL::TaskDecl<TaskUserDataManipulation>(this),
+    m_context(context)
+{
+    AddStep(&TaskUserDataManipulation::StartStep);
+    AddStep(&TaskUserDataManipulation::StepCreatePrivateStorageDir);
+    AddStep(&TaskUserDataManipulation::StepCreateSharedFolder);
+    AddStep(&TaskUserDataManipulation::StepLinkForPreload);
+    AddStep(&TaskUserDataManipulation::EndStep);
+}
+
+void TaskUserDataManipulation::StepCreatePrivateStorageDir()
+{
+
+    if (m_context.mode.installTime == InstallMode::InstallTime::FOTA
+        && m_context.isUpdateMode)
+    {
+        return;
+    }
+
+    if (m_context.mode.installTime == InstallMode::InstallTime::PRELOAD
+            || m_context.mode.installTime == InstallMode::InstallTime::FOTA) {
+        std::string userWidgetDir = m_context.locations->getUserDataRootDir();
+        _D("Create user data directory : %s", userWidgetDir.c_str());
+        WrtUtilMakeDir(userWidgetDir);
+    }
+    std::string storagePath = m_context.locations->getPrivateStorageDir();
+    _D("Create private storage directory : %s", m_context.locations->getPrivateStorageDir().c_str());
+
+    changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE);
+
+    if (m_context.isUpdateMode) { //update
+        std::string backData = m_context.locations->getBackupPrivateDir();
+        _D("copy private storage %s to %s", backData.c_str(), storagePath.c_str());
+        if (!DirectoryApi::DirectoryCopy(backData, storagePath)) {
+            _E("Failed to rename %s to %s", backData.c_str(), storagePath.c_str());
+            ThrowMsg(Exceptions::BackupFailed,
+                    "Error occurs copy private strage files");
+        }
+    }
+
+    std::string tempStoragePath = m_context.locations->getPrivateTempStorageDir();
+    _D("Create temp private storage directory : %s", tempStoragePath.c_str());
+    changeOwnerForDirectory(tempStoragePath, PRIVATE_STORAGE_MODE);
+
+    m_context.job->UpdateProgress(
+        InstallerContext::INSTALL_CREATE_PRIVATE_STORAGE,
+        "Create private storage for user");
+}
+
+void TaskUserDataManipulation::StepLinkForPreload()
+{
+    if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
+        std::string optRes = m_context.locations->getUserDataRootDir() +
+            WrtDB::GlobalConfig::GetWidgetResPath();
+        std::string usrRes = m_context.locations->getPackageInstallationDir() +
+            WrtDB::GlobalConfig::GetWidgetResPath();
+
+        std::string oldRes = optRes + ".old";
+
+        // Rename path if already exist.
+        if (0 == access(optRes.c_str(), F_OK)) {
+            if (-1 == rename(optRes.c_str(), oldRes.c_str())) {
+                _E("Failed To rename %s -> %s", optRes.c_str(), oldRes.c_str());
+            }
+        }
+
+        if (0 != access(optRes.c_str(), F_OK)) {
+            _D("Make symbolic name for preload app %s to %s", usrRes.c_str(), optRes.c_str());
+
+            if (symlink(usrRes.c_str(), optRes.c_str()) != 0)
+            {
+                int error = errno;
+                if (error)
+                    _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str());
+                ThrowMsg(Exceptions::FileOperationFailed,
+                        "Symbolic link creating is not done.");
+            }
+        }
+
+        /* link for data directory */
+        std::string storagePath = m_context.locations->getPrivateStorageDir();
+        std::string dataDir = m_context.locations->getPackageInstallationDir() +
+            "/" + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath();
+        if (0 != access(dataDir.c_str(), F_OK)) {
+            _D("Make symbolic name for preload app %s to %s", storagePath.c_str(), dataDir.c_str());
+
+            if (symlink(storagePath.c_str(), dataDir.c_str()) != 0)
+            {
+                int error = errno;
+                if (error)
+                    _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str());
+                ThrowMsg(Exceptions::FileOperationFailed,
+                        "Symbolic link creating is not done.");
+            }
+            changeOwnerForDirectory(dataDir, PRIVATE_STORAGE_MODE);
+        }
+
+        if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) {
+            std::string widgetBinPath = m_context.locations->getBinaryDir();
+            std::string userBinPath = m_context.locations->getUserBinaryDir();
+            std::string oldBinPath = userBinPath + ".old";
+
+            // Rename path if already exist.
+            if (0 == access(userBinPath.c_str(), F_OK)) {
+                if (-1 == rename(userBinPath.c_str(), oldBinPath.c_str())) {
+                    _E("Failed To rename %s -> %s", userBinPath.c_str(), oldBinPath.c_str());
+                }
+            }
+
+            _D("Make symbolic link for preload app %s to %s", widgetBinPath.c_str(), userBinPath.c_str());
+            if (symlink(widgetBinPath.c_str(), userBinPath.c_str()) != 0)
+            {
+                int error = errno;
+                if (error)
+                    _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str());
+                ThrowMsg(Exceptions::FileOperationFailed,
+                        "Symbolic link creating is not done.");
+            }
+
+        }
+    }
+}
+
+void TaskUserDataManipulation::StepCreateSharedFolder()
+{
+    if (m_context.mode.installTime == InstallMode::InstallTime::FOTA
+        && m_context.isUpdateMode)
+    {
+        return;
+    }
+
+    _D("StepCreateSharedFolder");
+    std::string sharedPath = m_context.locations->getSharedRootDir();
+    _D("Create shared directory : %s", m_context.locations->getSharedRootDir().c_str());
+
+    WrtUtilMakeDir(sharedPath);
+    WrtUtilMakeDir(m_context.locations->getSharedResourceDir());
+
+    changeOwnerForDirectory(m_context.locations->getSharedDataDir(),
+            SHARED_STORAGE_MODE);
+    changeOwnerForDirectory(m_context.locations->getSharedTrustedDir(),
+            SHARED_STORAGE_MODE);
+
+
+    // additional check for rootPath installation
+    // If this app is preloaded, "shared" diretory is already on place and do not needs to be moved
+    // TODO: why "shared" is on RW partion always but "data" and "tmp" are linked
+    if (m_context.isUpdateMode
+            && !(m_context.mode.rootPath == InstallMode::RootPath::RO
+            && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD)) {
+
+        /* Restore /shared/data */
+        _D("copy %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str());
+        if (!DirectoryApi::DirectoryCopy(
+                    m_context.locations->getBackupSharedDataDir(),
+                    m_context.locations->getSharedDataDir())) {
+                _E("Failed to rename %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str());
+                ThrowMsg(Exceptions::BackupFailed,
+                        "Error occurs copy shared strage files");
+            }
+
+        /* Restore /shared/trusted */
+        _D("copy %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str());
+        if (!DirectoryApi::DirectoryCopy(
+                    m_context.locations->getBackupSharedTrustedDir(),
+                    m_context.locations->getSharedTrustedDir())) {
+            _E("Failed to rename %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str());
+            ThrowMsg(Exceptions::BackupFailed,
+                    "Error occurs copy shared strage files");
+        }
+    }
+}
+
+void TaskUserDataManipulation::StartStep()
+{
+    LOGD("--------- <TaskUserDataManipulation> : START ----------");
+}
+
+void TaskUserDataManipulation::EndStep()
+{
+    LOGD("--------- <TaskUserDataManipulation> : END ----------");
+}
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/task_user_data_manipulation.h b/src_wearable/jobs/widget_install/task_user_data_manipulation.h
new file mode 100644 (file)
index 0000000..fbfabcc
--- /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_user_data_manipulation.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task user data folder 
+ */
+#ifndef JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H
+#define JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H
+
+#include <dpl/task.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+class TaskUserDataManipulation :
+    public DPL::TaskDecl<TaskUserDataManipulation>
+{
+    InstallerContext& m_context;
+
+    void StartStep();
+    void EndStep();
+    void StepCreatePrivateStorageDir();
+    void StepCreateSharedFolder();
+    void StepLinkForPreload();
+
+  public:
+    TaskUserDataManipulation(InstallerContext& context);
+};
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif //JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H 
diff --git a/src_wearable/jobs/widget_install/view_mode.h b/src_wearable/jobs/widget_install/view_mode.h
new file mode 100644 (file)
index 0000000..a4acc39
--- /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       view_mode.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#ifndef SRC_JOBS_WIDGET_INSTALL_VIEW_MODE_H_
+#define SRC_JOBS_WIDGET_INSTALL_VIEW_MODE_H_
+
+namespace Jobs {
+namespace WidgetInstall {
+enum ViewMode
+{
+    WINDOWED = 0,
+    FLOATING,
+    FULLSCREEN,
+    MAXIMIZED,
+    MINIMIZED
+};
+} // WidgetInstall
+} // Jobs
+
+#endif /* SRC_JOBS_WIDGET_INSTALL_VIEW_MODE_H_ */
diff --git a/src_wearable/jobs/widget_install/widget_install_context.h b/src_wearable/jobs/widget_install/widget_install_context.h
new file mode 100644 (file)
index 0000000..1e7e86d
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * 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 <map>
+#include <string>
+#include <boost/optional.hpp>
+#include <dpl/string.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <widget_install/widget_security.h>
+#include <feature_logic.h>
+#include <widget_location.h>
+#include <wrt_install_mode.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class JobWidgetInstall;
+} //namespace Jobs
+} //namespace WidgetInstall
+
+class WidgetModel;
+
+typedef std::map<DPL::String, bool> RequestedDevCapsMap;
+
+struct InstallerContext
+{
+    typedef enum InstallStepEnum
+    {
+        INSTALL_START = 0,
+        INSTALL_PARSE_CONFIG,
+        INSTALL_CHECK_FILE,
+
+        INSTALL_RDS_DELTA_CHECK,
+        INSTALL_RDS_PREPARE,
+
+        INSTALL_CREATE_BACKUP_DIR,                     /* For Update */
+        INSTALL_DIR_CREATE,
+        INSTALL_UNZIP_WGT,
+        INSTALL_WIDGET_CONFIG1,
+        INSTALL_WIDGET_CONFIG2,
+        INSTALL_DIGSIG_CHECK,
+        INSTALL_CERT_CHECK,
+        INSTALL_CERTIFY_LEVEL_CHECK,
+        INSTALL_CREATE_PRIVATE_STORAGE,
+        INSTALL_BACKUP_ICONFILE,                         /* For Update */
+        INSTALL_COPY_ICONFILE,
+        INSTALL_COPY_LIVEBOX_FILES,
+        INSTALL_CREATE_EXECFILE,
+        INSTALL_CREATE_MANIFEST,
+        INSTALL_ECRYPTION_FILES,
+        INSTALL_INSTALL_OSPSVC,
+        INSTALL_NEW_DB_INSERT,
+        INSTALL_ACE_PREPARE,
+        INSTALL_ACE_CHECK,
+        INSTALL_SMACK_ENABLE,
+        INSTALL_PKGINFO_UPDATE,
+        INSTALL_SET_CERTINFO,
+
+        INSTALL_END
+    } InstallStep;
+
+    // Installation state variables
+    WrtDB::WidgetRegisterInfo widgetConfig;      ///< WidgetConfigInfo
+    boost::optional<WidgetLocation> locations;
+    Jobs::WidgetInstall::WidgetSecurity widgetSecurity; ///< Widget Domain
+                                                  // information.
+    InstallStep installStep;              ///< current step of installation
+    Jobs::WidgetInstall::JobWidgetInstall *job;
+     ///< Whether this is an update or normal installation
+    Jobs::WidgetInstall::FeatureLogicPtr featureLogic;
+    /** List of dev-caps that are requested in widget config file.
+     * Additional flag tells whether dev cap gets "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). */
+    RequestedDevCapsMap staticPermittedDevCaps;
+    std::string installInfo;            ///<For recovery>
+    InstallLocationType locationType;
+    bool isUpdateMode;
+    InstallMode mode;
+    DPL::String callerPkgId;
+
+    std::string requestedPath; ///input path of widget
+    bool needEncryption;  ///for configuring right task if encryption needed
+    int certLevel;
+};
+
+#endif // INSTALLER_CONTEXT_H
diff --git a/src_wearable/jobs/widget_install/widget_install_errors.h b/src_wearable/jobs/widget_install/widget_install_errors.h
new file mode 100755 (executable)
index 0000000..59f44d5
--- /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    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>
+#include <job_exception_error.h>
+
+//TODO SafeException(...)
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace Exceptions {
+
+DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown)
+
+DECLARE_JOB_EXCEPTION(Base, OpenZipFailed, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, ZipEmpty, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, ExtractFileFailed, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, EmptyPluginsDirectory, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, PluginsSubdirectory, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, RDSDeltaFailure, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, MissingConfig, ErrorPackageInvalid)
+DECLARE_JOB_EXCEPTION(Base, InvalidStartFile, ErrorPackageInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, PackageLowerVersion, ErrorPackageLowerVersion)
+
+DECLARE_JOB_EXCEPTION(Base, ManifestInvalid, ErrorManifestInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, WidgetConfigFileNotFound, ErrorConfigNotFound)
+DECLARE_JOB_EXCEPTION(Base, WidgetConfigFileInvalid, ErrorConfigInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, SignatureNotFound, ErrorSignatureNotFound)
+
+DECLARE_JOB_EXCEPTION(Base, SignatureInvalid, ErrorSignatureInvalid)
+
+DECLARE_JOB_EXCEPTION(Base, SignatureVerificationFailed, ErrorSignatureVerificationFailed)
+
+DECLARE_JOB_EXCEPTION(Base, RootCertificateNotFound, ErrorRootCertificateNotFound)
+
+DECLARE_JOB_EXCEPTION(Base, CertificationInvaid, ErrorCertificationInvaid)
+DECLARE_JOB_EXCEPTION(Base, NotMatchedCertification, ErrorCertificationInvaid)
+
+DECLARE_JOB_EXCEPTION(Base, CertificateChainVerificationFailed, ErrorCertificateChainVerificationFailed)
+
+DECLARE_JOB_EXCEPTION(Base, CertificateExpired, ErrorCertificateExpired)
+
+DECLARE_JOB_EXCEPTION(Base, NotAllowed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, WidgetRunningError, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, DrmDecryptFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, RemovingFolderFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, RemovingFileFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, CreateVconfFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, CopyIconFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, FileOperationFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, InstallToExternalFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, BackupFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, InsertNewWidgetFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, RemoveBackupFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, UpdateFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, SetCertificateInfoFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, ErrorExternalInstallingFailure, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, GetInfoPkgMgrFailed, ErrorFatalError)
+
+DECLARE_JOB_EXCEPTION(Base, PackageAlreadyInstalled, ErrorPackageAlreadyInstalled)
+DECLARE_JOB_EXCEPTION(Base, AceCheckFailed, ErrorAceCheckFailed)
+DECLARE_JOB_EXCEPTION(Base, EncryptionFailed, ErrorEncryptionFailed)
+DECLARE_JOB_EXCEPTION(Base, InstallOspsvcFailed, ErrorInstallOspServcie)
+DECLARE_JOB_EXCEPTION(Base, PrivilegeLevelViolation, ErrorPrivilegeLevelViolation)
+DECLARE_JOB_EXCEPTION(Base, NotSupportRDSUpdate, ErrorNotSupportRDSUpdate)
+DECLARE_JOB_EXCEPTION(Base, SmackTransactionFailed, ErrorFatalError)
+DECLARE_JOB_EXCEPTION(Base, OutOfStorageFailed, ErrorOutOfStorage)
+DECLARE_JOB_EXCEPTION(Base, RecoveryFailed, ErrorFatalError)
+} //namespace
+} //namespace
+} //namespace
+
+#endif /* INSTALLER_ERRORS_H_ */
diff --git a/src_wearable/jobs/widget_install/widget_installer_struct.h b/src_wearable/jobs/widget_install/widget_installer_struct.h
new file mode 100644 (file)
index 0000000..1fd865e
--- /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    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_install_mode.h>
+#include <wrt_common_types.h>
+#include <pkgmgr_signal_interface.h>
+#include <memory>
+#include <string>
+
+//Widget Installer typedefs
+typedef void (*InstallerFinishedCallback)(
+    void *userParam,
+    std::string tizenId,
+    Jobs::Exceptions::Type);
+
+typedef void (*InstallerProgressCallback)(void *userParam,
+                                          ProgressPercent percent,
+                                          const ProgressDescription &);
+
+namespace Jobs {
+namespace WidgetInstall {
+//InstallationStruct
+typedef Jobs::JobCallbacksBase<InstallerFinishedCallback,
+                               InstallerProgressCallback>
+WidgetInstallCallbackBase;
+
+//Widget Installation Struct
+struct WidgetInstallationStruct : public WidgetInstallCallbackBase
+{
+    InstallMode m_installMode;
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgmgrInterface;
+
+    // It must be empty-constructible as a parameter of generic event
+    WidgetInstallationStruct() {};
+    WidgetInstallationStruct(
+        InstallerFinishedCallback finished,
+        InstallerProgressCallback progress,
+        void *param,
+        InstallMode mode,
+        std::shared_ptr<PackageManager::IPkgmgrSignal>
+        _pkgmgrInterface
+        ) :
+        WidgetInstallCallbackBase(finished, progress, param),
+        m_installMode(mode),
+        pkgmgrInterface(_pkgmgrInterface)
+    {}
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+
+#endif // WRT_SRC_INSTALLER_CORE_INSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_
diff --git a/src_wearable/jobs/widget_install/widget_security.cpp b/src_wearable/jobs/widget_install/widget_security.cpp
new file mode 100644 (file)
index 0000000..6a6a10f
--- /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    widget_security.cpp
+ * @author  Krzysztof Jackiewicz(k.jackiewicz@samsung.com)
+ * @version 1.0
+ * @brief
+ */
+
+#include "widget_security.h"
+#include <dpl/foreach.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+void WidgetSecurity::getCertificateChainList(
+    WrtDB::CertificateChainList& list,
+    WrtDB::CertificateSource source) const
+{
+    if (source == WrtDB::CertificateSource::SIGNATURE_AUTHOR) {
+        FOREACH(certIter, mAuthorsCertificateChainList)
+        list.push_back(certIter->toBase64String());
+    } else if (source == WrtDB::CertificateSource::SIGNATURE_DISTRIBUTOR) {
+        FOREACH(certIter, mCertificateChainList)
+        list.push_back(certIter->toBase64String());
+    } else if (source == WrtDB::CertificateSource::SIGNATURE_DISTRIBUTOR2) {
+        FOREACH(certIter, mCertificateChainList2)
+        list.push_back(certIter->toBase64String());
+    } else {
+        _E("UNKNOWN certificate");
+    }
+}
+} // namespace WidgetInstall
+} // namespace Jobs
diff --git a/src_wearable/jobs/widget_install/widget_security.h b/src_wearable/jobs/widget_install/widget_security.h
new file mode 100644 (file)
index 0000000..43673be
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * 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_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 WidgetSecurity : public WrtDB::IWidgetSecurity
+{
+  public:
+    WidgetSecurity() :
+        mRecognized(false),
+        mDistributorSigned(false)
+    {}
+
+    // from IWidgetSecurity
+    virtual const WrtDB::WidgetCertificateDataList& getCertificateList() const
+    {
+        return mCertificateList;
+    }
+
+    virtual bool isRecognized() const
+    {
+        return mRecognized;
+    }
+
+    virtual bool isDistributorSigned() const
+    {
+        return mDistributorSigned;
+    }
+
+    virtual void getCertificateChainList(
+        WrtDB::CertificateChainList& list,
+        WrtDB::CertificateSource source) const;
+
+    void setRecognized(bool recognized)
+    {
+        mRecognized = recognized;
+    }
+    void setDistributorSigned(bool distributorSigned)
+    {
+        mDistributorSigned = distributorSigned;
+    }
+    void setAuthorCertificatePtr(ValidationCore::CertificatePtr certPtr)
+    {
+        mAuthorCertificate = certPtr;
+    }
+
+    ValidationCore::CertificatePtr getAuthorCertificatePtr() const
+    {
+        return mAuthorCertificate;
+    }
+
+    ValidationCore::CertificateCollectionList& getCertificateChainListRef()
+    {
+        return mCertificateChainList;
+    }
+
+    ValidationCore::CertificateCollectionList& getCertificateChainList2Ref()
+    {
+        return mCertificateChainList2;
+    }
+
+    ValidationCore::CertificateCollectionList&
+    getAuthorsCertificateChainListRef()
+    {
+        return mAuthorsCertificateChainList;
+    }
+
+    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;
+    // 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;
+    // This certificates are for distributor2
+    ValidationCore::CertificateCollectionList mCertificateChainList2;
+    // This authors certificates are used by tizen
+    ValidationCore::CertificateCollectionList mAuthorsCertificateChainList;
+};
+} // namespace WidgetInstall
+} // namespace Jobs
+
+#endif /* WACSECURITY_H_ */
diff --git a/src_wearable/jobs/widget_install/widget_unzip.cpp b/src_wearable/jobs/widget_install/widget_unzip.cpp
new file mode 100644 (file)
index 0000000..70831ae
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * 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_unzip.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer widget unzip
+ */
+#include <widget_install/widget_unzip.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install/job_widget_install.h>
+#include <dpl/copy.h>
+#include <dpl/utils/path.h>
+#include <dpl/file_output.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <task_commons.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <dlfcn.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const char *const DRM_LIB_PATH = "/usr/lib/libdrm-service-core-tizen.so";
+const size_t SPACE_SIZE = 1024 * 1024;
+const char *const WEB_APP_CONFIG_XML= "config.xml";
+const char *const HYBRID_CONFIG_XML = "res/wgt/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));
+}
+}
+
+namespace Jobs {
+namespace WidgetInstall {
+
+WidgetUnzip::WidgetUnzip(const std::string &source)
+{
+    Try {
+        m_requestFile = getDecryptedPackage(source);
+        m_zip.reset(new DPL::ZipInput(m_requestFile));
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, source);
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, source);
+    }
+}
+
+void WidgetUnzip::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 WidgetUnzip::unzipProgress(const std::string &destination)
+{
+    // Show file info
+    _D("Unzipping: '%s', Comment: '%s', Compressed size: %lld, Uncompressed size: %lld",
+            m_zipIterator->name.c_str(), m_zipIterator->comment.c_str(), m_zipIterator->compressedSize, 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 = destination + "/" +
+            fileName.substr(0, fileName.size() - 1);
+        _D("Path to extract: %s", newPath.c_str());
+
+        // Create path in case of it is empty
+        createTempPath(newPath);
+    } else {
+        // This is regular file
+        std::string fileExtractPath = destination + "/" + fileName;
+
+        _D("File to extract: %s", fileExtractPath.c_str());
+
+        // Split into pat & file pair
+        PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath);
+
+        _D("Path and file: %s : %s", pathAndFile.path.c_str(), pathAndFile.file.c_str());
+
+        // First, ensure that path exists
+        createTempPath(pathAndFile.path);
+
+        Try
+        {
+            // Open file
+            std::unique_ptr<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()) {
+        _D("Unzip progress finished successfuly");
+    } else {
+        unzipProgress(destination);
+    }
+}
+
+bool WidgetUnzip::isDRMPackage(const std::string &source)
+{
+    _D("Enter : isDRMPackage()");
+    int ret = 0;
+    void* pHandle = NULL;
+    char* pErrorMsg = NULL;
+    int (*drm_oem_sapps_is_drm_file)(const char* pDcfPath, int dcfPathLen);
+
+    //TODO: quickfix for platform issues...
+    if(!DPL::Utils::Path(DRM_LIB_PATH).Exists())
+    {
+        _E("Cannot open %s!", DRM_LIB_PATH);
+        return false;
+    }
+
+    pHandle = dlopen(DRM_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
+    if (!pHandle) {
+        _E("dlopen failed : %s [%s]", source.c_str(), dlerror());
+        return false;
+    }
+
+    // clear existing error
+    dlerror();
+
+    drm_oem_sapps_is_drm_file = reinterpret_cast <int (*)(const char*, int)>
+        (dlsym(pHandle, "drm_oem_sapps_is_drm_file"));
+
+    if ((pErrorMsg = dlerror()) != NULL) {
+        _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+        dlclose(pHandle);
+        return false;
+    }
+
+    if (drm_oem_sapps_is_drm_file == NULL) {
+        _E("drm_oem_sapps_is_drm_file is NULL : %s", source.c_str());
+        dlclose(pHandle);
+        return false;
+    }
+
+    ret = drm_oem_sapps_is_drm_file(source.c_str(), source.length());
+    dlclose(pHandle);
+    if (1 == ret) {
+        _D("%s is DRM file", source.c_str());
+        return true;
+    }
+    _D("%s isn't DRM file", source.c_str());
+    return false;
+}
+
+bool WidgetUnzip::decryptDRMPackage(const std::string &source, const std::string
+        &decryptedSource)
+{
+    _D("Enter : decryptDRMPackage()");
+    int ret = 0;
+    void* pHandle = NULL;
+    char* pErrorMsg = NULL;
+    int (*drm_oem_sapps_decrypt_package)(const char* pDcfPath, int dcfPathLen,
+            const char* pDecryptedFile, int decryptedFileLen);
+
+    pHandle = dlopen(DRM_LIB_PATH, RTLD_LAZY | RTLD_GLOBAL);
+    if (!pHandle) {
+        _E("dlopen failed : %s [%s]", source.c_str(), dlerror());
+        return false;
+    }
+
+    // clear existing error
+    dlerror();
+
+    drm_oem_sapps_decrypt_package = reinterpret_cast <int (*)(const char*, int,
+            const char*, int)>
+        (dlsym(pHandle, "drm_oem_sapps_decrypt_package"));
+
+    if ((pErrorMsg = dlerror()) != NULL) {
+        _E("dlsym failed : %s [%s]", source.c_str(), pErrorMsg);
+        dlclose(pHandle);
+        return false;
+    }
+
+    if (drm_oem_sapps_decrypt_package == NULL) {
+        _E("drm_oem_sapps_decrypt_package is NULL : %s", source.c_str());
+        dlclose(pHandle);
+        return false;
+    }
+
+    ret = drm_oem_sapps_decrypt_package(source.c_str(), source.length(),
+            decryptedSource.c_str(), decryptedSource.length());
+    dlclose(pHandle);
+    if (1 == ret) {
+        _D("%s is decrypted : %s", source.c_str(), decryptedSource.c_str());
+        return true;
+    }
+    return false;
+}
+
+std::string WidgetUnzip::getDecryptedPackage(const std::string &source)
+{
+    _D("Check DRM...");
+    if (isDRMPackage(source)) {
+        std::string decryptedFile;
+        size_t found = source.find_last_of(".wgt");
+        if (found == std::string::npos) {
+            decryptedFile += source + "_tmp.wgt";
+        } else {
+            decryptedFile += source.substr(0, source.find_last_not_of(".wgt") +
+                    1) + "_tmp.wgt";
+        }
+
+        _D("decrypted file name : %s", decryptedFile.c_str());
+        if (!decryptDRMPackage(source, decryptedFile)) {
+            _E("Failed decrypt drm file");
+            ThrowMsg(Exceptions::DrmDecryptFailed, source);
+        }
+        return decryptedFile;
+    }
+    return source;
+}
+
+void WidgetUnzip::unzipWgtFile(const std::string &destination)
+{
+    _D("Prepare to unzip...");
+    Try
+    {
+        _D("wgtFile : %s", m_requestFile.c_str());
+        _D("Widget package comment: %s", m_zip->GetGlobalComment().c_str());
+
+        // Widget package must not be empty
+        if (m_zip->empty()) {
+            ThrowMsg(Exceptions::ZipEmpty, m_requestFile);
+        }
+
+        // Set iterator to first file
+        m_zipIterator = m_zip->begin();
+
+        unzipProgress(destination);
+
+        // Unzip finished, close internal structures
+        m_zip.reset();
+
+        // Done
+        _D("Unzip finished");
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, m_requestFile);
+    }
+    Catch(DPL::ZipInput::Exception::SeekFileFailed)
+    {
+        ThrowMsg(Exceptions::ExtractFileFailed, m_requestFile);
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, m_requestFile);
+    }
+}
+
+bool WidgetUnzip::checkAvailableSpace(const std::string &destination)
+{
+    _D("checkAvailableSpace ... ");
+
+    double unCompressedSize = m_zip->GetTotalUncompressedSize();
+    _D("unCompressedSize : %ld", unCompressedSize);
+
+    struct statvfs vfs;
+    if (-1 == statvfs(destination.c_str(), &vfs)) {
+        _E("There is no space for installation");
+        return false;
+    }
+
+    double freeSize = (double)vfs.f_bsize * vfs.f_bavail;
+    _D("Space Size : %ld", freeSize);
+
+    if (unCompressedSize + SPACE_SIZE >= freeSize) {
+        _E("There is no space for installation");
+        return false;
+    }
+    return true;
+}
+
+void WidgetUnzip::unzipConfiguration(const std::string &destination,
+        WrtDB::PackagingType* type)
+{
+    _D("unzipConfiguration");
+
+    Try {
+        _D("wgtFile : %s", m_requestFile.c_str());
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        Try {
+            configFile.reset(m_zip->OpenFile(HYBRID_CONFIG_XML));
+            *type = PKG_TYPE_HYBRID_WEB_APP;
+        } Catch(DPL::ZipInput::Exception::OpenFileFailed) {
+            configFile.reset(m_zip->OpenFile(WEB_APP_CONFIG_XML));
+            *type = PKG_TYPE_NOMAL_WEB_APP;
+        }
+
+        std::string extractPath = destination + "/" + WEB_APP_CONFIG_XML;
+        ExtractFile(configFile.get(), extractPath);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        ReThrowMsg(Exceptions::OpenZipFailed, m_requestFile);
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        ThrowMsg(Exceptions::ExtractFileFailed, "config.xml");
+    }
+    Catch(Exceptions::DrmDecryptFailed)
+    {
+        ReThrowMsg(Exceptions::ExtractFileFailed, m_requestFile);
+    }
+}
+
+} //namespace WidgetInstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_install/widget_unzip.h b/src_wearable/jobs/widget_install/widget_unzip.h
new file mode 100644 (file)
index 0000000..204cde7
--- /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    widget_unzip.cpp
+ * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for installer task unzip
+ */
+#ifndef WIDGET_UNZIP_H
+#define WIDGET_UNZIP_H
+
+#include <string>
+
+#include <dpl/zip_input.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class WidgetUnzip 
+{
+  public:
+      WidgetUnzip(const std::string &source);
+      void unzipWgtFile(const std::string &destination);
+      void unzipConfiguration(const std::string &destination, WrtDB::PackagingType *type);
+      bool checkAvailableSpace(const std::string &destination);
+
+  private:
+    // Unzip state
+    std::unique_ptr<DPL::ZipInput> m_zip;
+    DPL::ZipInput::const_iterator m_zipIterator;
+    std::string m_requestFile;
+
+    void unzipProgress(const std::string &destination);
+    void ExtractFile(DPL::ZipInput::File *input, const std::string
+            &destFileName);
+    bool isDRMPackage(const std::string &source);
+    bool decryptDRMPackage(const std::string &source, const std::string
+            &decryptedSource);
+    std::string getDecryptedPackage(const std::string &source);
+};
+
+} //namespace WidgetInstall
+} //namespace Jobs
+
+#endif // WIDGET_UNZIP_H
diff --git a/src_wearable/jobs/widget_install/widget_update_info.cpp b/src_wearable/jobs/widget_install/widget_update_info.cpp
new file mode 100644 (file)
index 0000000..7c292c7
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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::WidgetUpdateInfo(
+    const WrtDB::TizenAppId & appId,
+    const OptionalWidgetVersion &existingversion,
+    const OptionalWidgetVersion &incomingversion,
+            WrtDB::AppType type) :
+      tzAppId(appId),
+      existingVersion(existingversion),
+      incomingVersion(incomingversion),
+      appType(type)
+{
+}
+
diff --git a/src_wearable/jobs/widget_install/widget_update_info.h b/src_wearable/jobs/widget_install/widget_update_info.h
new file mode 100644 (file)
index 0000000..2021b42
--- /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    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
+{
+    WrtDB::TizenAppId tzAppId;
+    // Existing widget
+    OptionalWidgetVersion existingVersion;
+    // Incoming widget
+    OptionalWidgetVersion incomingVersion;
+    // widget type
+    WrtDB::AppType appType;
+
+    WidgetUpdateInfo() {};
+    WidgetUpdateInfo(const WrtDB::TizenAppId & tzAppid,
+                     const OptionalWidgetVersion &existringversion,
+                     const OptionalWidgetVersion &incomingVersion,
+                     const WrtDB::AppType type);
+};
+
+#endif // SRC_DOMAIN_WIDGET_UPDATE_INFO_H
diff --git a/src_wearable/jobs/widget_uninstall/job_widget_uninstall.cpp b/src_wearable/jobs/widget_uninstall/job_widget_uninstall.cpp
new file mode 100755 (executable)
index 0000000..9bb4897
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ * 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 <regex.h>
+#include <sys/stat.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/widget_uninstall_errors.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_remove_custom_handlers.h>
+#include <widget_uninstall/task_smack.h>
+#include <widget_uninstall/task_uninstall_ospsvc.h>
+#include <widget_uninstall/task_delete_pkginfo.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <pkg-manager/pkgmgr_signal.h>
+#include <app2ext_interface.h>
+#include <dpl/utils/path.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace { //anonymous
+const char* REG_TIZEN_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
+const int PKGID_LENTH = 10;
+const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps");
+
+bool checkDirectoryExist(const std::string& pkgId)
+{
+    DPL::Utils::Path installPath(GlobalConfig::GetUserInstalledWidgetPath());
+    installPath /= pkgId;
+    return installPath.Exists();
+}
+}
+
+namespace Jobs {
+namespace WidgetUninstall {
+
+class UninstallerTaskFail :
+    public DPL::TaskDecl<UninstallerTaskFail>
+{
+  private:
+    WidgetStatus m_status;
+
+    void StepFail()
+    {
+        if (WidgetStatus::NOT_INSTALLED == m_status) {
+            ThrowMsg(Jobs::WidgetUninstall::Exceptions::WidgetNotExist,
+                     "Widget does not exist");
+        } else if (WidgetStatus::PREALOAD == m_status) {
+            ThrowMsg(Jobs::WidgetUninstall::Exceptions::Unremovable,
+                     "Widget cann't uninstall");
+        } else {
+            Throw(Jobs::WidgetUninstall::Exceptions::Base);
+        }
+    }
+
+  public:
+    UninstallerTaskFail(WidgetStatus status) :
+        DPL::TaskDecl<UninstallerTaskFail>(this),
+        m_status(status)
+
+    {
+        AddStep(&UninstallerTaskFail::StepFail);
+    }
+};
+
+JobWidgetUninstall::JobWidgetUninstall(
+    const std::string & tizenPkgId,
+    const WidgetUninstallationStruct &
+    uninstallerStruct) :
+    Job(Uninstallation),
+    JobContextBase<WidgetUninstallationStruct>(uninstallerStruct),
+    m_id(tizenPkgId),
+    m_exceptionCaught(Jobs::Exceptions::Success)
+{
+    using namespace PackageManager;
+    m_context.removeStarted = false;
+    m_context.removeFinished = false;
+    m_context.removeAbnormal = false;
+    m_context.uninstallStep = UninstallerContext::UNINSTALL_START;
+    m_context.job = this;
+
+    Try
+    {
+        WidgetStatus status = getWidgetStatus(tizenPkgId);
+
+        if (WidgetStatus::Ok == status) {
+            //TODO: check and save type
+
+            WrtDB::WidgetDAOReadOnly dao(*m_context.tzAppIdList.begin());
+            m_context.tzPkgid = DPL::ToUTF8String(dao.getTizenPkgId());
+            m_context.locations = WidgetLocation(m_context.tzPkgid);
+            m_context.locations->registerAppid(DPL::ToUTF8String(*m_context.tzAppIdList.begin()));
+            m_context.installedPath =
+                DPL::Utils::Path(*dao.getWidgetInstalledPath());
+            m_context.manifestFile = getManifestFile();
+            PackagingType packagingType = dao.getPackagingType();
+
+            _D("Widget model exists. Pkg id : %s", m_context.tzPkgid.c_str());
+
+            // send start signal of pkgmgr
+            if (GetInstallerStruct().pkgmgrInterface->setPkgname(m_context.tzPkgid))
+            {
+                GetInstallerStruct().pkgmgrInterface->startJob(InstallationType::Uninstallation);
+            }
+
+            AddTask(new TaskCheck(m_context));
+            if (packagingType == PKG_TYPE_HYBRID_WEB_APP) {
+                AddTask(new TaskUninstallOspsvc(m_context));
+            }
+            AddTask(new TaskDeletePkgInfo(m_context));
+            AddTask(new TaskDbUpdate(m_context));
+            AddTask(new TaskSmack(m_context));
+
+            AddTask(new TaskRemoveCustomHandlers(m_context));
+            AddTask(new TaskRemoveFiles(m_context));
+        } else if (WidgetStatus::NOT_INSTALLED == status ||
+                WidgetStatus::PREALOAD == status) {
+            AddTask(new UninstallerTaskFail(status));
+        } else if (WidgetStatus::ABNORMAL == status) {
+            m_context.locations = WidgetLocation(m_context.tzPkgid);
+            m_context.removeAbnormal = true;
+            AddTask(new TaskRemoveFiles(m_context));
+        } else {
+            AddTask(new UninstallerTaskFail(WidgetStatus::UNRECOGNIZED));
+        }
+    } Catch(WidgetDAOReadOnly::Exception::Base) {
+        AddTask(new UninstallerTaskFail(WidgetStatus::UNRECOGNIZED));
+    }
+}
+
+WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id)
+{
+    regex_t regx;
+    if(regcomp(&regx, REG_TIZEN_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
+        _D("Regcomp failed");
+    }
+    std::string pkgId = id;
+    DPL::Utils::Path installPath;
+            if ((regexec(&regx, id.c_str(),
+        static_cast<size_t>(0), NULL, 0) != REG_NOERROR)) {
+        //appid was passed
+                pkgId = id.substr(0, PKGID_LENTH);
+
+        //Service app cannot uninstall by appid
+                WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(id));
+        if( dao.getWidgetType().appType == APP_TYPE_TIZENWEBSERVICE ){
+            _E("Service app cannot uninstall by appid");
+            return WidgetStatus::NOT_INSTALLED;
+            }
+            }
+
+    m_context.tzAppIdList = WrtDB::WidgetDAOReadOnly::getTzAppIdList(DPL::FromUTF8String(pkgId));
+    if( m_context.tzAppIdList.empty() ){
+                if(checkDirectoryExist(pkgId)) {
+                    _E("installed widget status is abnormal");
+                    return WidgetStatus::ABNORMAL;
+                }
+            return WidgetStatus::NOT_INSTALLED;
+        }
+    return WidgetStatus::Ok;
+}
+
+std::string JobWidgetUninstall::getRemovedTizenId() const
+{
+    return m_id;
+}
+
+bool JobWidgetUninstall::getRemoveStartedFlag() const
+{
+    return m_context.removeStarted;
+}
+
+bool JobWidgetUninstall::getRemoveFinishedFlag() const
+{
+    return m_context.removeFinished;
+}
+
+DPL::Utils::Path JobWidgetUninstall::getManifestFile() const
+{
+    std::ostringstream manifest_name;
+    manifest_name << m_context.tzPkgid << ".xml";
+    DPL::Utils::Path manifestFile;
+
+    const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps/" + m_context.tzPkgid);
+    const DPL::Utils::Path USR_PACKAGES_PATH("/usr/share/packages");
+    const DPL::Utils::Path OPT_PACKAGES_PATH("/opt/share/packages");
+
+    if (PRELOAD_INSTALLED_PATH == m_context.installedPath) {
+        _D("This widget is preloaded.");
+        manifestFile = USR_PACKAGES_PATH;
+    } else {
+        manifestFile = OPT_PACKAGES_PATH;
+    }
+
+    manifestFile /= manifest_name.str();
+    _D("Manifest file : %s", manifestFile.Fullpath().c_str());
+
+    return manifestFile;
+}
+
+void JobWidgetUninstall::SendProgress()
+{
+    using namespace PackageManager;
+    if (!getRemoveStartedFlag() ||
+        (getRemoveStartedFlag() && getRemoveFinishedFlag()))
+    {
+        if (NULL != GetInstallerStruct().progressCallback) {
+            // send progress signal of pkgmgr
+            std::ostringstream percent;
+            percent << static_cast<int>(GetProgressPercent());
+
+            _D("Call widget uninstall progressCallback");
+            GetInstallerStruct().progressCallback(
+                GetInstallerStruct().userParam,
+                GetProgressPercent(), GetProgressDescription());
+        }
+    }
+}
+
+void JobWidgetUninstall::SendFinishedSuccess()
+{
+    using namespace PackageManager;
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    _D("Call widget uninstall success finishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          getRemovedTizenId(),
+                                          Jobs::Exceptions::Success);
+}
+
+void JobWidgetUninstall::SendFinishedFailure()
+{
+    using namespace PackageManager;
+
+    LOGE(COLOR_ERROR "Error in uninstallation step: %d" COLOR_END, m_exceptionCaught);
+    LOGE(COLOR_ERROR "Message: %s" COLOR_END, m_exceptionMessage.c_str());
+    fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
+
+    // send signal of pkgmgr
+    GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
+
+    _D("Call widget uninstall failure finishedCallback");
+    GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
+                                          getRemovedTizenId(),
+                                          m_exceptionCaught);
+    _D("[JobWidgetUninstall] Asynchronous failure callback status sent");
+}
+
+void JobWidgetUninstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
+{
+    m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
+    m_exceptionMessage = e.GetMessage();
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/job_widget_uninstall.h b/src_wearable/jobs/widget_uninstall/job_widget_uninstall.h
new file mode 100755 (executable)
index 0000000..d7406ed
--- /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 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 <string>
+#include <job.h>
+#include <job_base.h>
+#include <widget_uninstall/widget_uninstaller_struct.h>
+#include <widget_uninstall/uninstaller_context.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+
+enum class WidgetStatus
+{
+    Ok, NOT_INSTALLED, PREALOAD, ABNORMAL, UNRECOGNIZED
+};
+
+typedef JobContextBase<WidgetUninstallationStruct> WidgetUnistallStructBase;
+typedef JobProgressBase<UninstallerContext::UninstallStep, UninstallerContext::UNINSTALL_END> UninstallContextBase;
+
+class JobWidgetUninstall :
+    public Job,
+    public UninstallContextBase,
+    public WidgetUnistallStructBase
+{
+  private:
+    UninstallerContext m_context;
+
+    //TODO move it to base class of all jobs
+    Jobs::Exceptions::Type m_exceptionCaught;
+    std::string m_exceptionMessage;
+    // It canbe pkgid or tzAppid
+    std::string m_id;
+
+  public:
+    /**
+     * @brief Uninstaller must to know which widget to uninstall.
+     *
+     * @param[in] WrtDB::TizenAppId tzAppId - widget to uninstall
+     */
+    JobWidgetUninstall(const std::string &tizenPkgIdorTizenAppId,
+                       const WidgetUninstallationStruct& uninstallerStruct);
+
+    std::string getRemovedTizenId() const;
+    bool getRemoveStartedFlag() const;
+    bool getRemoveFinishedFlag() const;
+    DPL::Utils::Path getManifestFile() const;
+
+    WidgetStatus getWidgetStatus(const std::string &tizenPkgIdorTizenAppId);
+
+    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_wearable/jobs/widget_uninstall/task_check.cpp b/src_wearable/jobs/widget_uninstall/task_check.cpp
new file mode 100755 (executable)
index 0000000..648cdf1
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * 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 <ctime>
+#include <dpl/sstream.h>
+#include <widget_uninstall/task_check.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <app_manager.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <installer_log.h>
+#include <web_provider_service.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskCheck::TaskCheck(UninstallerContext& context) :
+    DPL::TaskDecl<TaskCheck>(this),
+    m_context(context)
+{
+    AddStep(&TaskCheck::StartStep);
+    AddStep(&TaskCheck::StepUninstallPreCheck);
+    AddStep(&TaskCheck::StepCheckMDM);
+    AddStep(&TaskCheck::EndStep);
+}
+
+TaskCheck::~TaskCheck()
+{}
+
+void TaskCheck::StartStep()
+{
+    LOGD("--------- <TaskCheck> : START ----------");
+}
+
+void TaskCheck::EndStep()
+{
+    m_context.job->UpdateProgress(UninstallerContext::UNINSTALL_PRECHECK,
+                                  "Uninstall pre-checking Finished");
+    LOGD("--------- <TaskCheck> : END ----------");
+}
+
+void TaskCheck::StepUninstallPreCheck()
+{
+    FOREACH(it , m_context.tzAppIdList){
+        bool isRunning = false;
+        std::string tzAppId = DPL::ToUTF8String(*it);
+        int ret = app_manager_is_running(tzAppId.c_str(), &isRunning);
+        if (APP_MANAGER_ERROR_NONE != ret) {
+            _E("Fail to get running state");
+            ThrowMsg(Exceptions::PlatformAPIFailure,
+                 "Fail to get widget state");
+        }
+
+        if (true == isRunning) {
+            // get app_context for running application
+            // app_context must be released with app_context_destroy
+            app_context_h appCtx = NULL;
+            ret = app_manager_get_app_context(tzAppId.c_str(), &appCtx);
+            if (APP_MANAGER_ERROR_NONE != ret) {
+                _E("Fail to get app_context");
+                ThrowMsg(Exceptions::AppIsRunning,
+                     "Widget is not stopped. Cannot uninstall!");
+            }
+
+            // terminate app_context_h
+            ret = app_manager_terminate_app(appCtx);
+            if (APP_MANAGER_ERROR_NONE != ret) {
+                _E("Fail to terminate running application");
+                app_context_destroy(appCtx);
+                ThrowMsg(Exceptions::AppIsRunning,
+                     "Widget is not stopped. Cannot uninstall!");
+            } else {
+                app_context_destroy(appCtx);
+                // app_manager_terminate_app isn't sync API
+                // wait until application isn't running (50ms * 100)
+                bool isStillRunning = true;
+                int checkingloop = 100;
+                struct timespec duration = { 0, 50 * 1000 * 1000 };
+                while (--checkingloop >= 0) {
+                    nanosleep(&duration, NULL);
+                    int ret = app_manager_is_running(tzAppId.c_str(), &isStillRunning);
+                    if (APP_MANAGER_ERROR_NONE != ret) {
+                        _E("Fail to get running state");
+                        ThrowMsg(Exceptions::PlatformAPIFailure,
+                             "Fail to get widget state");
+                    }
+                    if (!isStillRunning) {
+                        break;
+                    }
+                }
+                if (isStillRunning) {
+                    _E("Fail to terminate running application");
+                    ThrowMsg(Exceptions::AppIsRunning,
+                         "Widget is not stopped. Cannot uninstall!");
+                }
+                _D("terminate application");
+            }
+        }
+    }
+
+    // check if this webapp has dynamic boxes, and request to remove them
+    web_provider_service_wait_boxes_removed(m_context.tzAppid.c_str());
+    _D("web app(%s) and its dynamic boxes can be terminated.", m_context.tzAppid.c_str());
+}
+
+void TaskCheck::StepCheckMDM()
+{
+    _D("StepCheckMDM");
+
+    if (PMINFO_R_OK !=  pkgmgr_parser_check_mdm_policy_for_uninstallation(
+                m_context.manifestFile.Fullpath().c_str())) {
+        _E("Failed to check mdm policy");
+        ThrowMsg(Exceptions::CheckMDMPolicyFailure, "Can't uninstall! Because of MDM policy");
+    }
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_check.h b/src_wearable/jobs/widget_uninstall/task_check.h
new file mode 100644 (file)
index 0000000..29c00db
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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();
+    void StepCheckMDM();
+    void StartStep();
+    void EndStep();
+
+  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_wearable/jobs/widget_uninstall/task_db_update.cpp b/src_wearable/jobs/widget_uninstall/task_db_update.cpp
new file mode 100755 (executable)
index 0000000..0c391fd
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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
+ */
+
+#ifdef DBOX_ENABLED
+#include <web_provider_livebox_info.h>
+#endif
+#include <widget_uninstall/task_db_update.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <ace_api_install.h>
+#include <dpl/assert.h>
+#include <ace-common/ace_api_common.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskDbUpdate::TaskDbUpdate(UninstallerContext& context) :
+    DPL::TaskDecl<TaskDbUpdate>(this),
+    m_context(context)
+{
+    AddStep(&TaskDbUpdate::StartStep);
+    AddStep(&TaskDbUpdate::StepRemoveExternalLocations);
+    AddStep(&TaskDbUpdate::StepDbUpdate);
+#ifdef DBOX_ENABLED
+    AddStep(&TaskDbUpdate::StepLiveboxDBDelete);
+#endif
+    AddStep(&TaskDbUpdate::EndStep);
+}
+
+TaskDbUpdate::~TaskDbUpdate()
+{}
+
+void TaskDbUpdate::StepDbUpdate()
+{
+    Try
+    {
+        //TODO: widget handle should not be used any more
+        FOREACH(it , m_context.tzAppIdList){
+            ace_unregister_widget(static_cast<ace_widget_handle_t>(WidgetDAOReadOnly::getHandle(*it)));
+            WidgetDAO::unregisterWidget(*it);
+        }
+        _D("Unregistered widget successfully!");
+    }
+    Catch(DPL::DB::SqlConnection::Exception::Base)
+    {
+        _E("Failed to handle StepDbUpdate!");
+        ReThrowMsg(Exceptions::DatabaseFailure,
+                   "Failed to handle StepDbUpdate!");
+    }
+}
+
+#ifdef DBOX_ENABLED
+void TaskDbUpdate::StepLiveboxDBDelete()
+{
+    FOREACH(it, m_context.tzAppIdList){
+    int ret =
+            web_provider_livebox_delete_by_app_id(DPL::ToUTF8String(*it).c_str());
+
+    if (ret < 0) {
+        _D("failed to delete box info");
+    } else {
+            _D("delete box info: %s", it);
+        }
+    }
+}
+#endif
+
+void TaskDbUpdate::StepRemoveExternalLocations()
+{
+    if (!m_context.removeAbnormal) {
+        FOREACH(it, m_context.tzAppIdList){
+            WidgetDAO dao(*it);
+            _D("Removing external locations:");
+            WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations();
+            FOREACH(file, externalPaths)
+            {
+                DPL::Utils::Path path(*file);
+                if(path.Exists()){
+                    if(path.IsFile()){
+                        _D("  -> %s", path.Fullpath().c_str());
+                        Try {
+                            DPL::Utils::Remove(path);
+                        } Catch(DPL::Utils::Path::BaseException){
+                            _E("Failed to remove the file: %s", path.Fullpath().c_str());
+                        }
+                    } else if (path.IsDir()){
+                        _D("  -> %s", path.Fullpath().c_str());
+                        Try {
+                            DPL::Utils::Remove(path);
+                        } Catch(DPL::Utils::Path::BaseException){
+                            Throw(Jobs::WidgetUninstall::TaskDbUpdate::
+                                Exception::RemoveFilesFailed);
+                        }
+                    }
+                } else {
+                    _W("  -> %s(no such a path)", path.Fullpath().c_str());
+                }
+            }
+            dao.unregisterAllExternalLocations();
+        }
+    }
+}
+
+void TaskDbUpdate::StartStep()
+{
+    LOGD("--------- <TaskDbUpdate> : START ----------");
+}
+
+void TaskDbUpdate::EndStep()
+{
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_DB_UPDATE,
+        "Widget DB Update Finished");
+
+    LOGD("--------- <TaskDbUpdate> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_db_update.h b/src_wearable/jobs/widget_uninstall/task_db_update.h
new file mode 100644 (file)
index 0000000..3b74ad5
--- /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_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 <string>
+#include <dpl/exception.h>
+#include <dpl/task.h>
+
+class UninstallerContext;
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskDbUpdate :
+    public DPL::TaskDecl<TaskDbUpdate>
+{
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, DbStepFailed)
+        DECLARE_EXCEPTION_TYPE(Base, RemoveFilesFailed)
+    };
+
+    UninstallerContext& m_context;
+
+  private:
+    void StepDbUpdate();
+    void StepLiveboxDBDelete();
+    void StepRemoveExternalLocations();
+
+    void StartStep();
+    void EndStep();
+
+  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_wearable/jobs/widget_uninstall/task_delete_pkginfo.cpp b/src_wearable/jobs/widget_uninstall/task_delete_pkginfo.cpp
new file mode 100644 (file)
index 0000000..cf2aa0e
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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_delete_pkginfo.cpp
+ * @author  Leerang Song(leerang.song@samsung.com)
+ * @version 1.0
+ * @brief   Implementation file for uninstaller delete package information
+ */
+
+#include <string.h>
+#include <widget_uninstall/task_delete_pkginfo.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <dpl/assert.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskDeletePkgInfo::TaskDeletePkgInfo(
+    UninstallerContext& context) :
+    DPL::TaskDecl<TaskDeletePkgInfo>(this),
+    m_context(context)
+{
+    AddStep(&TaskDeletePkgInfo::StartStep);
+    AddStep(&TaskDeletePkgInfo::StepDeletePkgInfo);
+    AddStep(&TaskDeletePkgInfo::EndStep);
+}
+
+void TaskDeletePkgInfo::StartStep()
+{
+    LOGD("--------- <TaskDeletePkgInfo> : START ----------");
+}
+
+void TaskDeletePkgInfo::EndStep()
+{
+    LOGD("--------- <TaskDeletePkgInfo> : END ----------");
+}
+
+void TaskDeletePkgInfo::StepDeletePkgInfo()
+{
+    std::ostringstream manifest_name;
+    manifest_name << m_context.tzPkgid << ".xml";
+    DPL::Utils::Path pre_manifest("/usr/share/packages");
+    pre_manifest /= manifest_name.str();
+
+    if (!(m_context.manifestFile.Exists() == 0 && pre_manifest.Exists())) {
+        if (0 !=  pkgmgr_parser_parse_manifest_for_uninstallation(
+                    m_context.manifestFile.Fullpath().c_str(), NULL)) {
+            _W("Manifest file failed to parse for uninstallation");
+        }
+    }
+    if (!DPL::Utils::TryRemove(m_context.manifestFile)) {
+        _W("No manifest file found: %s", m_context.manifestFile.Fullpath().c_str());
+    } else {
+        _D("Manifest file removed: %s", m_context.manifestFile.Fullpath().c_str());
+    }
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_delete_pkginfo.h b/src_wearable/jobs/widget_uninstall/task_delete_pkginfo.h
new file mode 100644 (file)
index 0000000..4624c4a
--- /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    task_delete_pkginfo.h
+ * @author  Leerang Song(leerang.song@samsung.com)
+ * @version 1.0
+ * @brief   Header file for uninstaller task delete package infomation
+ */
+
+#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DELETE_PKGINFO_H_
+#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DELETE_PKGINFO_H_
+
+#include <dpl/task.h>
+#include <string>
+
+struct UninstallerContext;
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskDeletePkgInfo :
+    public DPL::TaskDecl<TaskDeletePkgInfo>
+{
+    UninstallerContext& m_context;
+
+  private:
+    void StepDeletePkgInfo();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskDeletePkgInfo(UninstallerContext& context);
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif
+// WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_DELETE_PKGINFO_H_
diff --git a/src_wearable/jobs/widget_uninstall/task_remove_custom_handlers.cpp b/src_wearable/jobs/widget_uninstall/task_remove_custom_handlers.cpp
new file mode 100755 (executable)
index 0000000..4a7ad32
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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_custom_handlers.cpp
+ * @author  Przemyslaw Ciezkowski (p.ciezkowski@samsung.com)
+ * @version 1.0
+ * @brief   File for uninstaller - remove custom handlers
+ */
+
+#include <widget_uninstall/task_remove_custom_handlers.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <dpl/optional_typedefs.h>
+#include <appsvc.h>
+#include <wrt-commons/custom-handler-dao-ro/CustomHandlerDatabase.h>
+#include <wrt-commons/custom-handler-dao-rw/custom_handler_dao.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskRemoveCustomHandlers::TaskRemoveCustomHandlers(UninstallerContext& context)
+    :
+    DPL::TaskDecl<TaskRemoveCustomHandlers>(this),
+    m_context(context)
+{
+    AddStep(&TaskRemoveCustomHandlers::StartStep);
+    AddStep(&TaskRemoveCustomHandlers::Step);
+    AddStep(&TaskRemoveCustomHandlers::EndStep);
+}
+
+void TaskRemoveCustomHandlers::Step()
+{
+    CustomHandlerDB::Interface::attachDatabaseRW();
+    FOREACH(it, m_context.tzAppIdList){
+    _D("Removing widget from appsvc");
+        int result = appsvc_unset_defapp(DPL::ToUTF8String(*it).c_str());
+    _D("Result: %d", result);
+
+        CustomHandlerDB::CustomHandlerDAO handlersDao(*it);
+    handlersDao.removeWidgetProtocolHandlers();
+    handlersDao.removeWidgetContentHandlers();
+    }
+    CustomHandlerDB::Interface::detachDatabase();
+}
+
+void TaskRemoveCustomHandlers::StartStep()
+{
+    LOGD("--------- <TaskRemoveCustomHandlers> : START ----------");
+}
+
+void TaskRemoveCustomHandlers::EndStep()
+{
+    LOGD("--------- <TaskRemoveCustomHandlers> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_remove_custom_handlers.h b/src_wearable/jobs/widget_uninstall/task_remove_custom_handlers.h
new file mode 100644 (file)
index 0000000..e6458b9
--- /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_remove_custom_handlers.h
+ * @author  Przemyslaw Ciezkowski (p.ciezkowski@samsung.com)
+ * @version 1.0
+ * @brief   Header file for uninstaller - remove custom handlers
+ */
+#ifndef INSTALLER_CORE_JOBS_WIDGET_UNINSTALL_TASK_REMOVE_CUSTOM_HANDLERS_H
+#define INSTALLER_CORE_JOBS_WIDGET_UNINSTALL_TASK_REMOVE_CUSTOM_HANDLERS_H
+
+#include <dpl/task.h>
+
+class UninstallerContext;
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskRemoveCustomHandlers :
+    public DPL::TaskDecl<TaskRemoveCustomHandlers>
+{
+  private:
+    UninstallerContext& m_context;
+
+    void Step();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskRemoveCustomHandlers(UninstallerContext& context);
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOBS_WIDGET_UNINSTALL_TASK_REMOVE_CUSTOM_HANDLERS_H */
diff --git a/src_wearable/jobs/widget_uninstall/task_remove_files.cpp b/src_wearable/jobs/widget_uninstall/task_remove_files.cpp
new file mode 100644 (file)
index 0000000..daf4542
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * 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 <unistd.h>
+#include <widget_uninstall/task_remove_files.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/wrt-dao-ro/widget_config.h>
+#include <dpl/assert.h>
+#include <dpl/exception.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <ail.h>
+#include <pkgmgr/pkgmgr_parser.h>
+#include <errno.h>
+#include <string.h>
+#include <widget_install_to_external.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+using namespace WrtDB;
+
+TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) :
+    DPL::TaskDecl<TaskRemoveFiles>(this),
+    m_context(context)
+{
+    AddStep(&TaskRemoveFiles::StartStep);
+    AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory);
+    AddStep(&TaskRemoveFiles::StepRemoveFinished);
+    AddStep(&TaskRemoveFiles::EndStep);
+}
+
+TaskRemoveFiles::~TaskRemoveFiles()
+{}
+
+void TaskRemoveFiles::StepRemoveInstallationDirectory()
+{
+    _D("StepRemoveInstallationDirectory started");
+    Try {
+        int ret = app2ext_get_app_location(m_context.tzPkgid.c_str());
+
+        if (APP2EXT_SD_CARD == ret) {
+            _D("Remove external directory");
+            Try {
+                WidgetInstallToExtSingleton::Instance().initialize(m_context.tzPkgid);
+                WidgetInstallToExtSingleton::Instance().uninstallation();
+                WidgetInstallToExtSingleton::Instance().deinitialize();
+            }
+            Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
+            {
+                // Continue uninstall even fail to remove external directory.
+                // i.e.) SD card isn't inserted or unmounted.
+                // This behavior is recommended by platform(app2sd maintainer).
+                _E("Fail to remove external directory");
+            }
+         }
+        if (APP2EXT_NOT_INSTALLED != ret) {
+            _D("Removing directory");
+            m_context.removeStarted = true;
+            DPL::Utils::Path widgetDir= m_context.installedPath;
+            Try{
+                DPL::Utils::Remove(widgetDir);
+            } Catch(DPL::Utils::Path::BaseException){
+                _E("Removing widget installation directory failed : %s", widgetDir.Fullpath().c_str());
+            }
+            DPL::Utils::Path dataDir(m_context.locations->getUserDataRootDir());
+            Try{
+                DPL::Utils::Remove(dataDir);
+            } Catch(DPL::Utils::Path::BaseException){
+                _W("%s is already removed", dataDir.Fullpath().c_str());
+            }
+        } else {
+            _E("app is not installed");
+            ThrowMsg(Exceptions::WidgetNotExist, "failed to get app location");
+        }
+    } Catch(Exception::RemoveFilesFailed) {
+        ThrowMsg(Exceptions::RemoveFileFailure, "Cann't remove directory");
+    }
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_REMOVE_WIDGETDIR,
+        "Widget INstallation Directory Removal Finished");
+}
+
+void TaskRemoveFiles::StepRemoveFinished()
+{
+    _D("StepRemoveFinished finished");
+
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_REMOVE_FINISHED,
+        "Widget remove steps Finished");
+}
+
+void TaskRemoveFiles::StartStep()
+{
+    LOGD("--------- <TaskRemoveFiles> : START ----------");
+}
+
+void TaskRemoveFiles::EndStep()
+{
+    LOGD("--------- <TaskRemoveFiles> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_remove_files.h b/src_wearable/jobs/widget_uninstall/task_remove_files.h
new file mode 100644 (file)
index 0000000..276fb24
--- /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_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_
+
+//forward declaration
+struct UninstallerContext;
+
+#include <dpl/task.h>
+#include <dpl/log/log.h>
+
+#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;
+
+  private:
+    void StepRemoveInstallationDirectory();
+    void StepRemoveFinished();
+
+    void StartStep();
+    void EndStep();
+
+  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_wearable/jobs/widget_uninstall/task_smack.cpp b/src_wearable/jobs/widget_uninstall/task_smack.cpp
new file mode 100644 (file)
index 0000000..9599c92
--- /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    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/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <dpl/optional_typedefs.h>
+#include <installer_log.h>
+#include <privilege-control.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskSmack::TaskSmack(UninstallerContext& context) :
+    DPL::TaskDecl<TaskSmack>(this),
+    m_context(context)
+{
+    AddStep(&TaskSmack::StartStep);
+    AddStep(&TaskSmack::Step);
+    AddStep(&TaskSmack::EndStep);
+}
+
+void TaskSmack::Step()
+{
+    _D("------------------------> SMACK: Jobs::WidgetUninstall::TaskSmack::Step()");
+
+    if (PC_OPERATION_SUCCESS != perm_begin()) {
+        _E("failure in smack transaction begin");
+        return;
+    }
+
+    const char* pkgId = m_context.tzPkgid.c_str();
+    if (PC_OPERATION_SUCCESS != perm_app_revoke_permissions(pkgId)) {
+        _E("failure in revoking smack permissions");
+    }
+
+    if (PC_OPERATION_SUCCESS != perm_app_uninstall(pkgId)) {
+        _E("failure in removing smack rules file");
+    }
+
+    if (PC_OPERATION_SUCCESS != perm_end()) {
+        _E("failure in smack transaction end");
+        return;
+    }
+}
+
+void TaskSmack::StartStep()
+{
+    LOGD("--------- <TaskSmack> : START ----------");
+}
+
+void TaskSmack::EndStep()
+{
+    m_context.job->UpdateProgress(
+        UninstallerContext::UNINSTALL_SMACK_DISABLE,
+        "Widget SMACK Disabled");
+
+    LOGD("--------- <TaskSmack> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_smack.h b/src_wearable/jobs/widget_uninstall/task_smack.h
new file mode 100644 (file)
index 0000000..c7886b9
--- /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 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();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskSmack(UninstallerContext& context);
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif /* INSTALLER_CORE_JOS_WIDGET_UNINSTALL_TASK_SMACK_H */
diff --git a/src_wearable/jobs/widget_uninstall/task_uninstall_ospsvc.cpp b/src_wearable/jobs/widget_uninstall/task_uninstall_ospsvc.cpp
new file mode 100644 (file)
index 0000000..9d00ea1
--- /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.
+ */
+/**
+ * @file    task_uninstall_ospsvc.cpp
+ * @author  Soyoung Kim(sy037.kim@samsung.com)
+ * @version 1.0
+ * @brief   Header file for widget uninstall task to uninstall ospsvc
+ */
+#include <dpl/sstream.h>
+#include <dpl/utils/bash_utils.h>
+#include <widget_uninstall/task_uninstall_ospsvc.h>
+#include <widget_uninstall/job_widget_uninstall.h>
+#include <widget_uninstall/uninstaller_context.h>
+#include <widget_uninstall/widget_uninstall_errors.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace {
+const int MAX_BUF_SIZE = 128;
+const char* OSP_INSTALL_STR = "/usr/etc/package-manager/backend/tpk -uv ";
+}
+
+namespace Jobs {
+namespace WidgetUninstall {
+TaskUninstallOspsvc::TaskUninstallOspsvc(UninstallerContext& context) :
+    DPL::TaskDecl<TaskUninstallOspsvc>(this),
+    m_context(context)
+{
+    AddStep(&TaskUninstallOspsvc::StartStep);
+    AddStep(&TaskUninstallOspsvc::StepUninstallOspsvc);
+    AddStep(&TaskUninstallOspsvc::EndStep);
+}
+
+TaskUninstallOspsvc::~TaskUninstallOspsvc()
+{}
+
+void TaskUninstallOspsvc::StepUninstallOspsvc()
+{
+    _D("Step : Uninstall Osp service");
+
+    std::ostringstream commStr;
+    commStr << OSP_INSTALL_STR << BashUtils::escape_arg(m_context.tzPkgid);
+    _D("osp uninstall command : %s", commStr.str().c_str());
+
+    char readBuf[MAX_BUF_SIZE];
+    FILE *fd;
+    fd = popen(commStr.str().c_str(), "r");
+    if (NULL == fd) {
+        _E("Failed to uninstalltion osp service");
+        ThrowMsg(Exceptions::UninstallOspSvcFailed,
+                 "Error occurs during\
+                uninstall osp service");
+    }
+
+    if(fgets(readBuf, MAX_BUF_SIZE, fd) == NULL)
+    {
+        _E("Failed to uninstalltion osp service\
+                        Inability of reading file.");
+        ThrowMsg(Exceptions::UninstallOspSvcFailed,
+                "Error occurs during\
+                uninstall osp service");
+    }
+    _D("return value : %s", readBuf);
+
+    int result = atoi(readBuf);
+    if (0 != result) {
+        ThrowMsg(Exceptions::UninstallOspSvcFailed,
+                 "Error occurs during\
+                install osp service");
+    }
+
+    pclose(fd);
+
+    _D("Widget Can be uninstalled. Pkgname : %s", m_context.tzPkgid.c_str());
+    m_context.job->UpdateProgress(UninstallerContext::UNINSTALL_REMOVE_OSPSVC,
+                                  "Uninstall OSP service finished");
+}
+
+void TaskUninstallOspsvc::StartStep()
+{
+    LOGD("--------- <TaskUninstallOspsvc> : START ----------");
+}
+
+void TaskUninstallOspsvc::EndStep()
+{
+    LOGD("--------- <TaskUninstallOspsvc> : END ----------");
+}
+} //namespace WidgetUninstall
+} //namespace Jobs
diff --git a/src_wearable/jobs/widget_uninstall/task_uninstall_ospsvc.h b/src_wearable/jobs/widget_uninstall/task_uninstall_ospsvc.h
new file mode 100644 (file)
index 0000000..50ec347
--- /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_uninstall_ospsvc.h
+ * @author  Pawel Sikorski(p.sikorski@samsung.com)
+ * @version 1.0
+ * @brief   Header file for widget uninstall task to uninstall ospsvc
+ */
+
+#ifndef WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_UNINSTALL_OSPSVC_H
+#define WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_UNINSTALL_OSPSVC_H
+
+#include <dpl/task.h>
+
+struct UninstallerContext; //forward declaration
+
+namespace Jobs {
+namespace WidgetUninstall {
+class TaskUninstallOspsvc :
+    public DPL::TaskDecl<TaskUninstallOspsvc>
+{
+  private:
+    //context
+    UninstallerContext& m_context;
+
+    //steps
+    void StepUninstallOspsvc();
+
+    void StartStep();
+    void EndStep();
+
+  public:
+    TaskUninstallOspsvc(UninstallerContext& context);
+    virtual ~TaskUninstallOspsvc();
+};
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+#endif /* WRT_SRC_INSTALLER_CORE_JOB_WIDGET_UNINSTALL_TASK_UNINSTALL_OSPSVC_H */
diff --git a/src_wearable/jobs/widget_uninstall/uninstaller_context.h b/src_wearable/jobs/widget_uninstall/uninstaller_context.h
new file mode 100755 (executable)
index 0000000..ef1963f
--- /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    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 <boost/optional.hpp>
+#include <widget_uninstall/widget_uninstaller_struct.h>
+#include <widget_location.h>
+#include <dpl/utils/path.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+
+namespace Jobs {
+namespace WidgetUninstall {
+class JobWidgetUninstall;
+} //namespace WidgetUninstall
+} //namespace Jobs
+
+struct UninstallerContext
+{
+    enum UninstallStep
+    {
+        UNINSTALL_START,
+        UNINSTALL_PRECHECK,
+        UNINSTALL_REMOVE_WIDGETDIR,
+        UNINSTALL_REMOVE_DESKTOP,
+        UNINSTALL_REMOVE_FINISHED,
+        UNINSTALL_DB_UPDATE,
+        UNINSTALL_REMOVE_OSPSVC,
+        UNINSTALL_SMACK_DISABLE,
+        UNINSTALL_END
+    };
+
+    ///< flag that indicates whether installer starts
+    //to remove files.rStruct;
+    bool removeStarted;
+    ///< flag that indicates whether installer finishes
+    //to remove files completely.
+    bool removeFinished;
+
+    boost::optional<WidgetLocation> locations;
+
+    UninstallStep uninstallStep;       ///< current step of installation
+    Jobs::WidgetUninstall::JobWidgetUninstall *job;
+    std::list<DPL::String> tzAppIdList;
+    std::string tzAppid;
+    std::string tzPkgid;
+    std::string tzServiceid;
+    bool removeAbnormal;
+    DPL::Utils::Path installedPath;
+    DPL::Utils::Path manifestFile;
+    WrtDB::AppType appType;
+};
+
+#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_
diff --git a/src_wearable/jobs/widget_uninstall/widget_uninstall_errors.h b/src_wearable/jobs/widget_uninstall/widget_uninstall_errors.h
new file mode 100644 (file)
index 0000000..3c5970b
--- /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>
+#include <job_exception_error.h>
+
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetUninstall {
+namespace Exceptions {
+
+DECLARE_JOB_EXCEPTION_BASE(JobExceptionBase, Base, ErrorUnknown)
+
+DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, AlreadyUninstalling,
+        ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, AppIsRunning, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, WidgetNotExist, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, UninstallOspSvcFailed,
+        ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, PlatformAPIFailure, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, RemoveFileFailure, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, Unremovable, ErrorWidgetUninstallationFailed)
+DECLARE_JOB_EXCEPTION(Base, CheckMDMPolicyFailure, ErrorWidgetUninstallationFailed)
+} //namespace
+} //namespace
+} //namespace
+
+#endif /* WIDGET_UNINSTALL_ERRORS_H_ */
diff --git a/src_wearable/jobs/widget_uninstall/widget_uninstaller_struct.h b/src_wearable/jobs/widget_uninstall/widget_uninstaller_struct.h
new file mode 100644 (file)
index 0000000..3f33e4b
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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>
+#include <pkgmgr_signal_interface.h>
+#include <memory>
+
+//Widget Uninstaller typedefs
+typedef void (*UninstallerFinishedCallback)(
+    void *userParam,
+    std::string tizenId,
+    Jobs::Exceptions::Type);
+
+typedef void (*UninstallerProgressCallback)(
+    void *userParam,
+    ProgressPercent percent,
+    const ProgressDescription &description);
+
+//UninstallationStruct
+typedef Jobs::JobCallbacksBase<UninstallerFinishedCallback,
+                               UninstallerProgressCallback>
+WidgetUninstallCallbackBase;
+
+struct WidgetUninstallationStruct : public WidgetUninstallCallbackBase
+{
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgmgrInterface;
+
+    // It must be empty-constructible as a parameter of generic event
+    WidgetUninstallationStruct()
+    {}
+
+    WidgetUninstallationStruct(
+        UninstallerFinishedCallback finished,
+        UninstallerProgressCallback progress,
+        void *param,
+        std::shared_ptr<PackageManager::IPkgmgrSignal>
+        _pkgmgrInterface
+        ) :
+        WidgetUninstallCallbackBase(finished, progress, param),
+        pkgmgrInterface(_pkgmgrInterface)
+    {}
+};
+#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_
diff --git a/src_wearable/logic/installer_controller.cpp b/src_wearable/logic/installer_controller.cpp
new file mode 100644 (file)
index 0000000..d9b41d5
--- /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.
+ */
+#include "installer_controller.h"
+#include <dpl/singleton_impl.h>
+
+IMPLEMENT_SINGLETON(Logic::InstallerController)
+
+namespace Logic {
+InstallerController::InstallerController()
+{}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::InstallWidgetEvent &event)
+{
+    std::string fileName = event.GetArg0();
+    std::string pkgId = event.GetArg1();
+    Jobs::WidgetInstall::WidgetInstallationStruct installerStruct = event.GetArg2();
+    m_installerLogic.InstallWidget(fileName, pkgId, installerStruct);
+}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::InstallPluginEvent &event)
+{
+    std::string dirName = event.GetArg0();
+    PluginInstallerStruct installerStruct = event.GetArg1();
+    m_installerLogic.InstallPlugin(dirName, installerStruct);
+}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::UninstallWidgetEvent &event)
+{
+    std::string widgetPkgName = event.GetArg0();
+    WidgetUninstallationStruct uninstallerStruct = event.GetArg1();
+    m_installerLogic.UninstallWidget(widgetPkgName, uninstallerStruct);
+}
+
+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::InitializeEvent & /*event*/)
+{
+    m_installerLogic.Initialize();
+}
+
+void InstallerController::OnEventReceived(
+    const InstallerControllerEvents::TerminateEvent & /*event*/)
+{
+    m_installerLogic.Terminate();
+}
+} //Logic
+
diff --git a/src_wearable/logic/installer_controller.h b/src_wearable/logic/installer_controller.h
new file mode 100644 (file)
index 0000000..0cde86e
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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.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_3(InstallWidgetEvent,
+            std::string,              // zipFileName
+            std::string,              // package id
+            Jobs::WidgetInstall::WidgetInstallationStruct) // 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 inicietig widget uninstallation.
+ *
+ * tizen id is used to point witch widget shuld be uninstalled
+ */
+DECLARE_GENERIC_EVENT_2(UninstallWidgetEvent,
+                        std::string,
+                        WidgetUninstallationStruct)
+
+/**
+ * @brief Event for pushing installation process forward.
+ */
+DECLARE_GENERIC_EVENT_1(NextStepEvent, Jobs::Job *)
+
+DECLARE_GENERIC_EVENT_0(InitializeEvent)
+DECLARE_GENERIC_EVENT_0(TerminateEvent)
+} // namespace InstallerEvents
+
+namespace Logic {
+/**
+ * @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::UninstallWidgetEvent,
+    InstallerControllerEvents::NextStepEvent,
+    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 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::InitializeEvent &event);
+    virtual void OnEventReceived(
+        const InstallerControllerEvents::TerminateEvent &event);
+
+  private:
+    // Embedded logic
+    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_wearable/logic/installer_logic.cpp b/src_wearable/logic/installer_logic.cpp
new file mode 100755 (executable)
index 0000000..b80c98b
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * 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 <dpl/wrt-dao-rw/feature_dao.h>
+#include <dpl/wrt-dao-rw/plugin_dao.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>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace Logic {
+InstallerLogic::InstallerLogic() :
+    m_job(0),
+    m_NextHandle(0)
+{}
+
+InstallerLogic::~InstallerLogic()
+{
+    if (m_job) {
+        delete m_job;
+    }
+}
+
+void InstallerLogic::Initialize()
+{
+    _D("Done");
+}
+
+void InstallerLogic::Terminate()
+{
+    //TODO how to delete, if it is still running, paused and so on
+    if(m_job)
+        m_job->SetPaused(true);
+
+    _D("Done");
+}
+
+Jobs::JobHandle InstallerLogic::AddAndStartJob()
+{
+    Jobs::JobHandle handle = GetNewJobHandle();
+    m_job->SetJobHandle(handle);
+    //Start job
+    CONTROLLER_POST_EVENT(InstallerController,
+                          InstallerControllerEvents::NextStepEvent(m_job));
+
+    return handle;
+}
+
+//InstallWidget, UninstallWidget InstallPlugin method are almost the same
+// But each Job has different constructor, so creating new Job is specific
+Jobs::JobHandle InstallerLogic::InstallWidget(
+    const std::string & widgetPath,
+    const std::string & pkgId,
+    const Jobs::WidgetInstall::WidgetInstallationStruct &
+    installerStruct)
+{
+    if(m_job)
+    {
+        _E("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
+    _D("New Widget Installation:");
+
+    m_job = new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, pkgId, installerStruct);
+
+    return AddAndStartJob();
+}
+
+Jobs::JobHandle InstallerLogic::UninstallWidget(
+    const std::string & widgetPkgName,
+    const
+    WidgetUninstallationStruct &uninstallerStruct)
+{
+    if(m_job)
+    {
+        _E("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
+    _D("New Widget Uninstallation");
+
+    m_job  =
+        new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName,
+                                                      uninstallerStruct);
+
+      return AddAndStartJob();
+}
+
+Jobs::JobHandle InstallerLogic::InstallPlugin(
+    std::string const & pluginPath,     // TODO change type to PluginPath
+    const PluginInstallerStruct &
+    installerStruct)
+{
+    if(m_job)
+    {
+        _E("Job is in progress. It is impossible to add new job");
+        return -1;
+    }
+
+    _D("New Plugin Installation");
+
+    // TODO Conversion to PluginPath is temporary
+    m_job =
+        new Jobs::PluginInstall::JobPluginInstall(PluginPath(pluginPath), installerStruct);
+
+    // before start install plugin, reset plugin data which is stopped
+    // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS)
+    ResetProgressPlugins();
+
+    return AddAndStartJob();
+}
+
+#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();
+
+        job->SendProgress();
+
+        if (stepSucceded) {
+            return !job->IsPaused();
+        }
+
+        if (!job->GetAbortStarted()) {
+            //job successfully finished
+
+            //send finished callback
+            job->SendFinishedSuccess();
+
+            switch (job->GetInstallationType()) {
+            case Jobs::PluginInstallation:
+                InstallWaitingPlugins();
+                break;
+            default: //because of warning
+                break;
+            }
+        } else {
+            //job abort process completed
+            job->SendFinishedFailure();
+        }
+
+        //clean job
+        delete job;
+        m_job=0;
+
+        return false;
+    } catch (Jobs::JobExceptionBase &exc) {
+        //start revert job
+        _D("Exception occured: %d. Reverting job...", exc.getParam());
+        bool hasAbortSteps = job->Abort();
+        job->SetAbortStarted(true);
+        job->SaveExceptionData(exc);
+
+        if (!hasAbortSteps) {
+            //no AbortSteps
+            job->SendFinishedFailure();
+
+            //clean job
+            delete job;
+            m_job=0;
+        }
+        return hasAbortSteps;
+    }
+}
+
+//TODO implement me
+bool InstallerLogic::AbortJob(const Jobs::JobHandle & /*handle*/)
+{
+    _W("Not implemented");
+    return true;
+}
+void InstallerLogic::InstallWaitingPlugins()
+{
+    PluginHandleSetPtr waitingPlugins;
+
+    waitingPlugins =
+        PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_WAITING);
+
+    FOREACH(it, *waitingPlugins)
+    {
+        resolvePluginDependencies(*it);
+    }
+}
+
+void InstallerLogic::ResetProgressPlugins()
+{
+    PluginHandleSetPtr progressPlugins;
+
+    progressPlugins =
+        PluginDAO::getPluginHandleByStatus(PluginDAO::INSTALLATION_IN_PROGRESS);
+
+    FOREACH(it, *progressPlugins) {
+        FeatureHandleListPtr featureListPtr =
+            FeatureDAOReadOnly::GetFeatureHandleListForPlugin(*it);
+        FOREACH(ItFeature, *featureListPtr) {
+            FeatureDAO::UnregisterFeature(*ItFeature);
+        }
+        PluginDAO::unregisterPlugin(*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)
+        {
+            _E("Library implementing: %s NOT FOUND", (*requiredObject).c_str());
+
+            //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_wearable/logic/installer_logic.h b/src_wearable/logic/installer_logic.h
new file mode 100755 (executable)
index 0000000..3e87a44
--- /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.
+ */
+#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-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>
+
+namespace Logic {
+class InstallerLogic
+{
+    Jobs::Job* m_job;
+
+    void ResetProgressPlugins();
+    void InstallWaitingPlugins();
+    bool resolvePluginDependencies(PluginHandle handle);
+
+    Jobs::JobHandle m_NextHandle;
+    Jobs::JobHandle GetNewJobHandle()
+    {
+        return m_NextHandle++;
+    }
+    Jobs::JobHandle AddAndStartJob();
+
+  public:
+    virtual ~InstallerLogic();
+
+    void Initialize();
+
+    void Terminate();
+
+    Jobs::JobHandle InstallWidget(
+        const std::string & widgetPath,
+        const std::string & pkgId,
+        const Jobs::WidgetInstall::WidgetInstallationStruct &
+        installerStruct);
+
+    Jobs::JobHandle UninstallWidget(
+        const std::string & widgetPkgName,
+        const WidgetUninstallationStruct &
+        uninstallerStruct);
+
+    Jobs::JobHandle InstallPlugin(std::string const & pluginPath,
+                                  const PluginInstallerStruct &installerStruct);
+
+    bool NextStep(Jobs::Job* installModel);
+
+    bool AbortJob(const Jobs::JobHandle &handle);
+
+  private:
+    InstallerLogic();
+
+    friend class InstallerController;
+};
+}
+
+#endif // INSTALLER_LOGIC_H
diff --git a/src_wearable/misc/feature_logic.cpp b/src_wearable/misc/feature_logic.cpp
new file mode 100755 (executable)
index 0000000..9c1c9ee
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * 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-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <installer_log.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+namespace {
+const DPL::String PRIVILEGE_TESTAUTOMATION =
+    L"http://tizen.org/privilege/testautomation";
+const DPL::String DEVICE_CAPABILITY_TESTAUTOMATION = L"testautomation";
+}
+FeatureLogic::FeatureLogic(const WrtDB::TizenAppId & tzAppid) :
+    m_rejected(false)
+{
+    WrtDB::WidgetDAOReadOnly widgetDao(tzAppid);
+    WidgetFeatureSet featureSet = widgetDao.getFeaturesList();
+    FOREACH(it, featureSet) {
+        _D("Feature name : %ls", it->name.c_str());
+        WrtDB::DeviceCapabilitySet dcs;
+        if (!DPL::StringCompare(it->name, PRIVILEGE_TESTAUTOMATION)) {
+            // special privilege
+            // This privilege doesn't have plugin in the target
+            // only use to special behavior
+            dcs.insert(DEVICE_CAPABILITY_TESTAUTOMATION);
+        } else {
+            // normal privilege
+            dcs = WrtDB::FeatureDAOReadOnly::GetDeviceCapability(it->name);
+        }
+        FOREACH(devCap, dcs) {
+            _D("--- dev cap  : %ls", (*devCap).c_str());
+        }
+        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)
+{
+    AssertMsg(isProcessable(), "Wrong usage");
+    if (!allowed) {
+        m_currentFeature->rejected = true;
+        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_wearable/misc/feature_logic.h b/src_wearable/misc/feature_logic.h
new file mode 100644 (file)
index 0000000..d407cb0
--- /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.
+ */
+
+#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 <memory>
+
+#include <dpl/wrt-dao-ro/feature_dao_read_only.h>
+#include <wrt_common_types.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class FeatureLogic : DPL::Noncopyable
+{
+  public:
+
+    FeatureLogic(const WrtDB::TizenAppId & tzAppid);
+
+    bool isDone() const;
+
+    bool next();
+
+    void setAceResponse(bool allowed);
+
+    DPL::String getDevice() const;
+
+    bool isRejected(void) const
+    {
+        return m_rejected;
+    }
+
+    struct Feature : public WidgetFeature {
+        WrtDB::DeviceCapabilitySet devCapSet;
+        WrtDB::DeviceCapabilitySet::const_iterator currentCap;
+
+        Feature(const WidgetFeature &wf,
+                const WrtDB::DeviceCapabilitySet &set) :
+            WidgetFeature(wf)
+            , devCapSet(set)
+        {
+            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;
+            rejected = second.rejected;
+            pluginId = second.pluginId;
+            currentCap = devCapSet.find(*second.currentCap);
+        }
+    };
+
+    typedef std::list<Feature> FeatureList;
+    typedef FeatureList::const_iterator FeatureIterator;
+
+    FeatureIterator resultBegin()
+    {
+        return m_featureList.begin();
+    }
+    FeatureIterator resultEnd()
+    {
+        return m_featureList.end();
+    }
+
+  private:
+    bool isProcessable() const;
+
+    FeatureList m_featureList;
+    FeatureList::iterator m_currentFeature;
+    bool m_rejected;
+};
+
+typedef std::shared_ptr<FeatureLogic> FeatureLogicPtr;
+} // namespace WidgetInstall
+} // namespace Jobs
+
+#endif // SRC_INSTALLER_MISC_FEATURE_LOGIC
diff --git a/src_wearable/misc/libxml_utils.cpp b/src_wearable/misc/libxml_utils.cpp
new file mode 100644 (file)
index 0000000..114e95b
--- /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    libxml_utils.cpp
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ */
+
+#include "libxml_utils.h"
+
+#include <dpl/singleton_impl.h>
+#include <installer_log.h>
+
+IMPLEMENT_SINGLETON(LibxmlUtils)
+
+LibxmlUtils::LibxmlUtils() : isInitialized(false)
+{}
+
+LibxmlUtils::~LibxmlUtils()
+{
+    if (isInitialized) {
+        _D("Libxml - cleaning");
+        // Cleanup function for the XML library.
+        xmlCleanupParser();
+        //this is to debug memory for regression tests
+        xmlMemoryDump();
+    }
+}
+
+void LibxmlUtils::init()
+{
+    if (!isInitialized) {
+        LIBXML_TEST_VERSION
+            isInitialized = true;
+        _D("Libxml have been initialized");
+    }
+    _D("Libxml already initialized");
+}
+
diff --git a/src_wearable/misc/libxml_utils.h b/src_wearable/misc/libxml_utils.h
new file mode 100644 (file)
index 0000000..5354bda
--- /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    libxml_utils.h
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ */
+
+#ifndef LIBXML_UTILS_H
+#define LIBXML_UTILS_H
+
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+#include <dpl/singleton.h>
+#include <dpl/log/log.h>
+#include <dpl/string.h>
+#include <dpl/exception.h>
+
+/**
+ * @brief The LibxmlUtils class
+ *
+ * Singleton for assurence for libxml2 initialization
+ *
+ * Use: LibxmlUtils::Instance().init(); to initialize library
+ *
+ */
+class LibxmlUtils
+{
+  public:
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, Libxml2Error)
+
+    LibxmlUtils();
+    ~LibxmlUtils();
+
+    void init();
+
+  private:
+    bool isInitialized;
+
+    friend class DPL::Singleton<LibxmlUtils>;
+};
+
+typedef DPL::Singleton<LibxmlUtils> LibxmlSingleton;
+
+#endif // LIBXML_UTILS_H
diff --git a/src_wearable/misc/plugin_path.cpp b/src_wearable/misc/plugin_path.cpp
new file mode 100644 (file)
index 0000000..2b2ebdb
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2013 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_path_builder.cpp
+ * @author  Kamil Nować (k.nowac@partner.samgsung.com)
+ * @version
+ * @brief
+ */
+
+#include <plugin_path.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dlfcn.h>
+
+using namespace DPL::Utils;
+
+PluginPath::PluginPath(const Path& fullPath) : Path(fullPath.Fullpath())
+{
+    setLibraryCombinedName(
+            WrtDB::GlobalConfig::GetPluginPrefix(),
+            WrtDB::GlobalConfig::GetPluginSuffix());
+};
+PluginPath::PluginPath(const std::string& fullPath) : Path(fullPath)
+{
+    setLibraryCombinedName(
+            WrtDB::GlobalConfig::GetPluginPrefix(),
+            WrtDB::GlobalConfig::GetPluginSuffix());
+};
+PluginPath::PluginPath(const DPL::String& fullPath) : Path(fullPath)
+{
+    setLibraryCombinedName(
+            WrtDB::GlobalConfig::GetPluginPrefix(),
+            WrtDB::GlobalConfig::GetPluginSuffix());
+};
+PluginPath::PluginPath(){}
+
+PluginPath PluginPath::getMetaFile() const
+{
+    PluginPath metaFile = *this;
+    return metaFile /= WrtDB::GlobalConfig::GetPluginMetafileName();
+}
\ No newline at end of file
diff --git a/src_wearable/misc/plugin_path.h b/src_wearable/misc/plugin_path.h
new file mode 100644 (file)
index 0000000..8ada790
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2013 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_path_builder.cpp
+ * @author  Kamil Nować (k.nowac@partner.samgsung.com)
+ * @version
+ * @brief
+ */
+
+#ifndef PLUGIN_PATH_H
+#define PLUGIN_PATH_H
+
+#include <string>
+#include <dpl/string.h>
+#include <dpl/utils/path.h>
+
+class PluginPath: public DPL::Utils::Path{
+private:
+    std::string m_library;
+
+public:
+    PluginPath(const DPL::Utils::Path& fullPath);
+    PluginPath(const std::string& fullPath);
+    PluginPath(const DPL::String& fullPath);
+    PluginPath();
+
+    //getMetafile() this function adds metafile to current path.
+    PluginPath getMetaFile() const;
+
+    //setLibraryCombinedName This function creates name for library by adding
+    //prefix and suffix to PluginPath object filename.
+    void setLibraryCombinedName(const std::string& prefix, const std::string& sufix)
+    {
+      this->m_library = prefix + this->Filename() + sufix;
+    }
+
+    //getLibraryName returns library name
+    const std::string& getLibraryName() const
+    {
+        return m_library;
+    }
+    //getLibraryPath returns full path to the library
+    const PluginPath getLibraryPath() const
+    {
+        return this->operator /(m_library);
+    }
+};
+
+#endif // PLUGIN_PATH_H
diff --git a/src_wearable/misc/wac_widget_id.cpp b/src_wearable/misc/wac_widget_id.cpp
new file mode 100644 (file)
index 0000000..dca752b
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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/string.h>
+
+#include <iri.h>
+#include <installer_log.h>
+
+namespace {
+const char *SCHEME_HTTP = "http";
+const char *SCHEME_HTTPS = "https";
+}
+
+WacWidgetId::WacWidgetId(const DPL::OptionalString &widgetId) :
+    m_schemaMatch(false)
+{
+    if (!!widgetId) {
+        std::string wid = DPL::ToUTF8String(*widgetId);
+        parse(wid.c_str());
+    }
+}
+
+bool WacWidgetId::matchHost(const DPL::String &second) const
+{
+    _D("m_schemaMatch is: %d", m_schemaMatch);
+    if (!m_schemaMatch) {
+        return false;
+    }
+
+    _D("Matching DNS identity: %s %ls", m_host.c_str(), second.c_str());
+
+    return m_host == DPL::ToUTF8String(second);
+}
+
+void WacWidgetId::parse(const char *url)
+{
+    _D("Widget id to parse: %s", url);
+
+    std::unique_ptr<iri_struct, std::function<void(iri_struct*)> >
+    iri(iri_parse(url), iri_destroy);
+
+    if (!iri.get()) {
+        _E("Error in parsing widget id.");
+        return; // m_schemaMatch == false;
+    }
+
+    std::string scheme;
+
+    if (iri.get()->scheme) {
+        scheme = iri.get()->scheme;
+    } else {
+        _W("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)) {
+        _W("Unknown scheme in widget id. %s", scheme.c_str());
+        return; // m_schemaMatch == false;
+    } else {
+        m_schemaMatch = true;
+    }
+
+    if (iri.get()->host) {
+        m_host = iri.get()->host;
+        _D("Host has been set to: %s", m_host.c_str());
+    }
+
+    // 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_wearable/misc/wac_widget_id.h b/src_wearable/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_wearable/misc/widget_install_to_external.cpp b/src_wearable/misc/widget_install_to_external.cpp
new file mode 100644 (file)
index 0000000..b0219dd
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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_install_to_external.cpp
+ * @author      Soyoung Kim (sy037.kim@smasung.com)
+ */
+#include "widget_install_to_external.h"
+
+#include <dpl/singleton_safe_impl.h>
+#include <dpl/assert.h>
+#include <installer_log.h>
+
+IMPLEMENT_SAFE_SINGLETON(WidgetInstallToExt)
+
+WidgetInstallToExt::WidgetInstallToExt() :
+    m_handle(NULL),
+    m_appId("")
+{}
+
+WidgetInstallToExt::~WidgetInstallToExt()
+{}
+
+void WidgetInstallToExt::initialize(std::string appId)
+{
+    _D("WidgetInstallToExt::initialize()");
+    m_appId = appId;
+
+    if (NULL == m_handle) {
+        m_handle = app2ext_init(APP2EXT_SD_CARD);
+        if (NULL == m_handle) {
+            ThrowMsg(Exception::ErrorInstallToExt, "initialize failed");
+        }
+    }
+}
+
+void WidgetInstallToExt::deinitialize()
+{
+    _D("WidgetInstallToExt::deinitialize()");
+    if (NULL != m_handle) {
+        if (0 < app2ext_deinit(m_handle)) {
+            ThrowMsg(Exception::ErrorInstallToExt,
+                     "app2ext deinitialize \
+                    failed");
+        }
+    }
+}
+
+void WidgetInstallToExt::preInstallation(GList *dirList, int dSize)
+{
+    _D("WidgetInstallToExt::preInstallation()");
+    Assert(m_handle);
+
+    int ret = m_handle->interface.pre_install(m_appId.c_str(), dirList, dSize);
+
+    if (APP2EXT_SUCCESS == ret) {
+        _D("App2Ext pre install success");
+    } else {
+        postInstallation(false);
+        ThrowMsg(Exception::ErrorInstallToExt, "pre-install failed");
+    }
+}
+
+void WidgetInstallToExt::postInstallation(bool status)
+{
+    _D("WidgetInstallToExt::postInstallation()");
+
+    if (NULL != m_handle) {
+        if (status) {
+            m_handle->interface.post_install(m_appId.c_str(),
+                                             APP2EXT_STATUS_SUCCESS);
+        } else {
+            m_handle->interface.post_install(m_appId.c_str(),
+                                             APP2EXT_STATUS_FAILED);
+        }
+    }
+}
+
+void WidgetInstallToExt::preUpgrade(GList *dirList, int dSize)
+{
+    _D("WidgetInstallToExt::preUpgrade()");
+    Assert(m_handle);
+
+    int ret = m_handle->interface.pre_upgrade(m_appId.c_str(), dirList, dSize);
+    if (APP2EXT_SUCCESS == ret) {
+        _D("App2Ext pre-upgrade success");
+    } else {
+        postUpgrade(false);
+        ThrowMsg(Exception::ErrorInstallToExt, "pre-upgrade failed");
+    }
+}
+
+void WidgetInstallToExt::postUpgrade(bool status)
+{
+    _D("WidgetInstallToExt::postUpgrade()");
+    if (NULL != m_handle) {
+        if (status) {
+            m_handle->interface.post_upgrade(m_appId.c_str(),
+                                             APP2EXT_STATUS_SUCCESS);
+        } else {
+            m_handle->interface.post_upgrade(m_appId.c_str(),
+                                             APP2EXT_STATUS_FAILED);
+        }
+    }
+}
+
+void WidgetInstallToExt::uninstallation()
+{
+    _D("WidgetInstallToExt::uninstallation()");
+
+    Assert(m_handle);
+
+    int ret = m_handle->interface.pre_uninstall(m_appId.c_str());
+    if (APP2EXT_SUCCESS == ret) {
+        if (APP2EXT_SUCCESS ==
+            m_handle->interface.post_uninstall(m_appId.c_str()))
+        {
+            _D("App2Ext pre-uninstall success");
+        } else {
+            ThrowMsg(Exception::ErrorInstallToExt, "post-uninstall failed");
+        }
+    } else {
+        ThrowMsg(Exception::ErrorInstallToExt, "pre-uninstall failed");
+    }
+}
+
+void WidgetInstallToExt::disable()
+{
+    _D("WidgetInstallToExt::disable()");
+    if (NULL != m_handle) {
+        int ret = m_handle->interface.disable(m_appId.c_str());
+        if (APP2EXT_SUCCESS != ret && APP2EXT_ERROR_UNMOUNT != ret) {
+            ThrowMsg(Exception::ErrorInstallToExt, "disable failed");
+        }
+    }
+}
diff --git a/src_wearable/misc/widget_install_to_external.h b/src_wearable/misc/widget_install_to_external.h
new file mode 100644 (file)
index 0000000..cc9c4df
--- /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        widget_install_to_external.h
+ * @author      Soyoung Kim (sy037.kim@smasung.com)
+ */
+#ifndef WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
+#define WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
+
+#include <string>
+#include <dpl/singleton.h>
+#include <dpl/string.h>
+#include <app2ext_interface.h>
+
+class WidgetInstallToExt
+{
+  public:
+    class Exception
+    {
+      public:
+        DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, ErrorInstallToExt)
+    };
+
+    void initialize(std::string appId);
+    void deinitialize();
+    void preInstallation(GList* dirList, int dSize);
+    void postInstallation(bool status);
+    void preUpgrade(GList* dirList, int dSize);
+    void postUpgrade(bool status);
+    void uninstallation();
+    void disable();
+
+  private:
+    app2ext_handle *m_handle;
+    std::string m_appId;
+
+    WidgetInstallToExt();
+    ~WidgetInstallToExt();
+
+    friend class DPL::Singleton<WidgetInstallToExt>;
+};
+
+typedef DPL::Singleton<WidgetInstallToExt> WidgetInstallToExtSingleton;
+
+#endif // WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
diff --git a/src_wearable/misc/widget_location.cpp b/src_wearable/misc/widget_location.cpp
new file mode 100755 (executable)
index 0000000..00f1037
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * 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_location.cpp
+ * @author      Iwanek Tomasz (t.iwanek@smasung.com)
+ */
+#include "widget_location.h"
+
+#include <unistd.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/assert.h>
+#include <dpl/sstream.h>
+#include <dpl/localization/localization_utils.h>
+#include <widget_install/task_commons.h>
+#include <installer_log.h>
+
+WidgetLocation::DirectoryDeletor::DirectoryDeletor(bool isReadOnly) :
+    m_dirpath(Jobs::WidgetInstall::createTempPath(isReadOnly))
+{}
+
+WidgetLocation::DirectoryDeletor::DirectoryDeletor(std::string tempPath) :
+        m_dirpath(tempPath)
+{}
+
+WidgetLocation::DirectoryDeletor::~DirectoryDeletor()
+{
+    _D("Removing widget installation temporary directory: %s", m_dirpath.c_str());
+    std::string roPath = WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+
+    if (0 != m_dirpath.compare(0, roPath.length(), roPath)) {
+        if (!WrtUtilRemove(m_dirpath)) {
+            _W("Fail at removing directory: %s", m_dirpath.c_str());
+        }
+    }
+}
+
+std::string WidgetLocation::DirectoryDeletor::getTempPath() const
+{
+    return m_dirpath;
+}
+
+WidgetLocation::WidgetLocation() :
+    m_temp(new WidgetLocation::DirectoryDeletor(true))
+{}
+
+WidgetLocation::WidgetLocation(const std::string & widgetname) :
+    m_pkgid(widgetname),
+    m_temp(new WidgetLocation::DirectoryDeletor(false))
+{}
+
+WidgetLocation::~WidgetLocation()
+{}
+
+WidgetLocation::WidgetLocation(const std::string & widgetname,
+                               std::string sourcePath,
+                               WrtDB::PackagingType t,
+                               bool isReadonly,
+                               InstallMode::ExtensionType eType) :
+    m_pkgid(widgetname),
+    m_widgetSource(sourcePath),
+    m_type(t),
+    m_temp(
+        new WidgetLocation::DirectoryDeletor(isReadonly)),
+    m_extensionType(eType)
+{
+    if (isReadonly) {
+        m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+    } else {
+        m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    }
+    if (access(m_widgetSource.c_str(), F_OK) != 0) {
+        m_widgetSource = m_installedPath + "/" + m_pkgid;
+    }
+}
+
+WidgetLocation::WidgetLocation(const std::string & widgetname,
+                               std::string sourcePath,
+                               std::string dirPath,
+                               WrtDB::PackagingType t,
+                               bool isReadonly,
+                               InstallMode::ExtensionType eType) :
+    m_pkgid(widgetname),
+    m_widgetSource(sourcePath),
+    m_type(t),
+    m_temp(new WidgetLocation::DirectoryDeletor(dirPath)),
+    m_extensionType(eType)
+{
+    if (isReadonly) {
+        m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+    } else {
+        m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
+    }
+    if (access(m_widgetSource.c_str(), F_OK) != 0) {
+        m_widgetSource = m_installedPath + "/" + m_pkgid;
+    }
+}
+
+// TODO cache all these paths
+std::string WidgetLocation::getInstallationDir() const
+{
+    return m_installedPath;
+}
+
+std::string WidgetLocation::getPackageInstallationDir() const
+{
+    return m_installedPath + "/" + m_pkgid;
+}
+
+std::string WidgetLocation::getSourceDir() const
+{
+    return m_installedPath + "/"
+           + m_pkgid + WrtDB::GlobalConfig::GetWidgetSrcPath();
+}
+
+std::string WidgetLocation::getBinaryDir() const
+{
+    return m_installedPath + "/"
+           + m_pkgid + WrtDB::GlobalConfig::GetUserWidgetExecPath();
+}
+
+std::string WidgetLocation::getUserBinaryDir() const
+{
+    return getUserDataRootDir() + "/"
+           + WrtDB::GlobalConfig::GetUserWidgetExecPath();
+}
+
+std::string WidgetLocation::getExecFile() const
+{
+    return getBinaryDir() + "/" + m_appid;
+}
+
+std::string WidgetLocation::getBackupDir() const
+{
+    return getPackageInstallationDir() + ".backup";
+}
+
+std::string WidgetLocation::getBackupSourceDir() const
+{
+    return getBackupDir() + WrtDB::GlobalConfig::GetWidgetSrcPath();
+}
+
+std::string WidgetLocation::getBackupBinaryDir() const
+{
+    return getBackupDir() + WrtDB::GlobalConfig::GetUserWidgetExecPath();
+}
+
+std::string WidgetLocation::getBackupExecFile() const
+{
+    return getBackupBinaryDir() + "/" + m_appid;
+}
+
+std::string WidgetLocation::getBackupPrivateDir() const
+{
+    return getBackupDir() + "/" +
+        WrtDB::GlobalConfig::GetWidgetPrivateStoragePath();
+}
+
+std::string WidgetLocation::getUserDataRootDir() const
+{
+    return std::string(WrtDB::GlobalConfig::GetWidgetUserDataPath()) +
+           "/" + m_pkgid;
+}
+
+std::string WidgetLocation::getPrivateStorageDir() const
+{
+    return getUserDataRootDir() + "/" +
+           WrtDB::GlobalConfig::GetWidgetPrivateStoragePath();
+}
+
+std::string WidgetLocation::getPrivateTempStorageDir() const
+{
+    return getUserDataRootDir() + "/" +
+           WrtDB::GlobalConfig::GetWidgetPrivateTempStoragePath();
+}
+
+
+std::string WidgetLocation::getTemporaryPackageDir() const
+{
+    return m_temp->getTempPath();
+}
+
+std::string WidgetLocation::getTemporaryRootDir() const
+{
+    if (m_extensionType == InstallMode::ExtensionType::DIR) {
+        return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath();
+    }
+    return getSourceDir();
+}
+
+DPL::String WidgetLocation::getPkgId() const
+{
+    return DPL::FromUTF8String(m_pkgid);
+}
+
+std::string WidgetLocation::getInstalledIconPath() const
+{
+    return m_iconPath;
+}
+
+std::string WidgetLocation::getWidgetSource() const
+{
+    return m_widgetSource;
+}
+
+void WidgetLocation::setIconTargetFilenameForLocale(const std::string & icon)
+{
+    m_iconPath = icon;
+}
+
+void WidgetLocation::registerExternalLocation(const std::string & file)
+{
+    m_externals.push_back(file);
+}
+
+WrtDB::ExternalLocationList WidgetLocation::listExternalLocations() const
+{
+    return m_externals;
+}
+
+void WidgetLocation::registerAppid(const std::string & appid)
+{
+    m_appid = appid;
+}
+
+#ifdef SERVICE_ENABLED
+void WidgetLocation::registerServiceAppid(const std::string & svcAppid)
+{
+    m_svcAppid = svcAppid;
+}
+#endif
+
+std::string WidgetLocation::getSharedRootDir() const
+{
+    /* TODO : add wrt-commons*/
+    return getUserDataRootDir() + "/shared";
+}
+
+std::string WidgetLocation::getSharedResourceDir() const
+{
+    return getSharedRootDir() + "/res";
+}
+
+std::string WidgetLocation::getSharedDataDir() const
+{
+    return getSharedRootDir() + "/data";
+}
+
+std::string WidgetLocation::getSharedTrustedDir() const
+{
+    return getSharedRootDir() + "/trusted";
+}
+
+std::string WidgetLocation::getBackupSharedDir() const
+{
+    return getBackupDir() + "/shared";
+}
+
+std::string WidgetLocation::getBackupSharedDataDir() const
+{
+    return getBackupSharedDir() + "/data";
+}
+
+std::string WidgetLocation::getBackupSharedTrustedDir() const
+{
+    return getBackupSharedDir() + "/trusted";
+}
+
+std::string WidgetLocation::getNPPluginsExecFile() const
+{
+    return getBinaryDir() + "/" + m_appid + ".npruntime";
+}
+
+std::string WidgetLocation::getNPPluginsDir() const
+{
+    return getSourceDir() + "/plugins";
+}
diff --git a/src_wearable/misc/widget_location.h b/src_wearable/misc/widget_location.h
new file mode 100755 (executable)
index 0000000..f7fd546
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * 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_location.h
+ * @author      Iwanek Tomasz (t.iwanek@smasung.com)
+ */
+#ifndef WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
+#define WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
+
+#include <string>
+#include <memory>
+
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <wrt_common_types.h>
+#include <wrt_install_mode.h>
+
+/**
+ * @brief The WidgetLocation class
+ *
+ * Object that stores locations of several files/directories according
+ * to package name
+ *
+ * Current package layout (of installed package) is following:
+ *
+ * /opt/apps/[package_name]
+ *           \_____________ /data
+ *           \_____________ /share
+ *           \_____________ /bin
+ *           \_____________ /bin/[id_of_installed_package]
+ *           \_____________ /res/wgt/
+ *                               \___ config.xml
+ *                               \___ [widgets_archive_content]
+ *
+ * 1) Normal Widget
+ *  Developer provides content of res/wgt directory (package contains that
+ * directory as root).
+ *
+ * 2) For OSP Service Hybrid App is actually a bit different:
+ *  Root is OSP Service directory, WebApp content is located in [root]/res/wgt
+ *
+ * Temporary directory is directory when widget is placed at the begining
+ * of installation process. After parsing process of config.xml, destination
+ * directory is created.
+ */
+class WidgetLocation
+{
+    class DirectoryDeletor
+    {
+      public:
+        DirectoryDeletor();
+        DirectoryDeletor(std::string tempPath);
+        DirectoryDeletor(bool isPreload);
+
+        ~DirectoryDeletor();
+        std::string getTempPath() const;
+
+      private:
+        std::string m_dirpath;
+    };
+
+  public:
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, NoTemporaryPath)
+    /**
+     * @brief WidgetLocation
+     *
+     * Creates useless object. Needed by optional type
+     */
+    WidgetLocation();
+    /**
+     * @brief WidgetLocation Builds paths for widget location during
+     * uninstallation
+     *
+     * Uninstallation process needs only installed package directory.
+     *
+     * @param widgetname name of widget
+     */
+    explicit WidgetLocation(const std::string & widgetname);
+    /**
+     * @brief WidgetLocation Builds paths for widget location during
+     * installation
+     *
+     * @param widgetname name of widget
+     * @param sourcePath given source path
+     * @param t declaraced type of widget if type is needed
+     *
+     * In destruction removes temporary directory
+     */
+    WidgetLocation(const std::string & widgetname, std::string sourcePath,
+                   WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
+                   bool isReadonly = false,
+                   InstallMode::ExtensionType eType =
+                   InstallMode::ExtensionType::WGT);
+
+    WidgetLocation(const std::string & widgetname, std::string sourcePath,
+                   std::string dirPath,
+                   WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
+                   bool isReadonly = false,
+                   InstallMode::ExtensionType eType =
+                   InstallMode::ExtensionType::WGT);
+
+    ~WidgetLocation();
+
+    // Installed paths
+    std::string getInstallationDir() const; // /opt/apps or /usr/apps
+    std::string getPackageInstallationDir() const; // /opt/apps/[package]
+    std::string getSourceDir() const;  // /opt/apps/[package]/res/wgt
+    std::string getBinaryDir() const;  // /opt/apps/[package]/bin or /usr/apps/[package]/bin
+    std::string getUserBinaryDir() const;  // /opt/apps/[package]/bin
+    std::string getExecFile() const;   // /opt/apps/[package]/bin/[package]
+    std::string getBackupDir() const;  // /opt/apps/[package].backup
+    std::string getBackupSourceDir() const; // /opt/apps/[pkg].backup/res/wgt
+    std::string getBackupBinaryDir() const; // /opt/apps/[pkg].backup/bin
+    std::string getBackupExecFile() const;  // /opt/apps/[pkg].backup/bin/[pkg]
+    std::string getBackupPrivateDir() const;  // /opt/apps/[pkg].backup/data
+    std::string getUserDataRootDir() const; // /opt/usr/apps/[package]
+    std::string getPrivateStorageDir() const; // /opt/usr/apps/[package]/data
+    std::string getPrivateTempStorageDir() const; // /opt/usr/apps/[package]/tmp
+    std::string getSharedRootDir() const; // /opt/usr/apps/[package]/shared
+    std::string getSharedResourceDir() const; // /opt/usr/apps/[package]/shared/res
+    std::string getSharedDataDir() const; // /opt/usr/apps/[package]/shared/data
+    std::string getSharedTrustedDir() const; // /opt/usr/apps/[package]/shared/trusted
+    std::string getBackupSharedDir() const; // /opt/usr/apps/[package].backup/shared
+    std::string getBackupSharedDataDir() const; // /opt/usr/apps/[package].backup/shared/data
+    std::string getBackupSharedTrustedDir() const; // /opt/usr/apps/[package].backup/shared/trusted
+    std::string getNPPluginsDir() const; // /opt/usr/apps/[package]/res/wgt/plugins
+    std::string getNPPluginsExecFile() const; // /opt/usr/apps/[package]/bin/{execfile}
+
+    // Temporary paths
+    /**
+     * @brief getTemporaryRootDir
+     * @return value of root for developer's provide package (root of unpacked
+     * .wgt file)
+     */
+    std::string getTemporaryPackageDir() const;
+    /**
+     * @brief getTemporaryRootDir
+     *
+     * Value of this will differs according to type of installed widget.
+     *
+     * @return value of root for content in temporary directory to be copied
+     * into 'res/wgt'
+     */
+    std::string getTemporaryRootDir() const;
+
+    //icons
+    /**
+     * @brief setIconTargetFilenameForLocale set installed ion path according to
+     * locale
+     * @param icon path of application icon
+     */
+    void setIconTargetFilenameForLocale(const std::string &icon);
+
+    /**
+     * @brief getIconTargetFilename gets icon full path
+     * @param languageTag language tag
+     * @return value of full path
+     */
+    std::string getInstalledIconPath() const;
+
+    /**
+     * @brief getWidgetSourcePath return widget's source path given to installer
+     * @return value of source path
+     */
+    std::string getWidgetSource() const;
+    /**
+     * @brief pkgid Returns pkgid
+     * @return pkgid
+     */
+    DPL::String getPkgId() const;
+
+    //external files
+    /**
+     * @brief registerExternalFile Registers file for database registration
+     * @param file
+     *
+     * Registered file will be stored in database and removed automatically a
+     *
+     * @return
+     */
+    void registerExternalLocation(const std::string & file);
+    /**
+     * @brief listExternalFile list all file to be registered
+     */
+    WrtDB::ExternalLocationList listExternalLocations() const;
+
+    /*
+     * @brief set appid
+     */
+    void registerAppid(const std::string & appid);
+#ifdef SERVICE_ENABLED
+    void registerServiceAppid(const std::string & svcAppid);
+#endif
+
+  private:
+    std::string m_pkgid;                        //id of package
+    std::string m_widgetSource;                   // Source widget zip
+                                                  // file/widget url
+    std::string m_appid;                        //id of app
+#ifdef SERVICE_ENABLED
+    std::string m_svcAppid;
+#endif
+    std::string m_iconPath;                       //installed icon path
+    WrtDB::PackagingType m_type;
+    std::shared_ptr<DirectoryDeletor> m_temp;      //directory
+    WrtDB::ExternalLocationList m_externals;
+    std::string m_installedPath;
+    InstallMode::ExtensionType m_extensionType;
+};
+
+#endif // WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H
diff --git a/src_wearable/pkg-manager/CMakeLists.txt b/src_wearable/pkg-manager/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..d65c064
--- /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.
+#
+
+SET(BACKLIB_SRCS
+    backendlib.cpp
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser/widget_parser.cpp
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser/parser_runner.cpp
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser/ignoring_parser.cpp
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser/deny_all_parser.cpp
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser/libiriwrapper.cpp
+    ${PROJECT_SOURCE_DIR}/src/wrt-installer/language_subtag_rst_tree.cpp
+)
+
+PKG_CHECK_MODULES(WRT_BACKLIB_PKGS
+    dpl-efl
+    dpl-wrt-dao-ro
+    dpl-wrt-dao-rw
+    dpl-utils-efl
+    pkgmgr-installer
+    pkgmgr-types
+    pkgmgr
+    dlog
+    libpcrecpp
+    wrt-commons-i18n-dao-ro
+    REQUIRED)
+
+INCLUDE_DIRECTORIES(
+    ${WRT_BACKLIB_PKGS_INCLUDE_DIRS}
+    ${PROJECT_SOURCE_DIR}/src/configuration_parser
+)
+
+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"
+)
+
+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_wearable/pkg-manager/DESCRIPTION b/src_wearable/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_wearable/pkg-manager/backendlib.cpp b/src_wearable/pkg-manager/backendlib.cpp
new file mode 100644 (file)
index 0000000..4260d1e
--- /dev/null
@@ -0,0 +1,570 @@
+/*
+ * 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 <package-manager.h>
+#include <regex.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <vcore/VCore.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.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/foreach.h>
+#include <dpl/utils/folder_size.h>
+#include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/copy.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/zip_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/file_input.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/localization/LanguageTagsProvider.h>
+#include <dpl/optional_typedefs.h>
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+#include <installer_log.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
+
+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);
+
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path);
+
+static void pkg_native_plugin_on_unload()
+{
+    _D("pkg_native_plugin_unload() is called");
+}
+
+static int pkg_plugin_app_is_installed(const char *pkg_name)
+{
+    const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
+    _D("pkg_plugin_app_is_installed() is called");
+
+    WrtDB::WrtDatabase::attachToThreadRO();
+
+    regex_t reg;
+    if (regcomp(&reg, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+        _D("Regcomp failed");
+    }
+
+    WrtDB::TizenAppId appid;
+
+    if (!(regexec(&reg, pkg_name,
+                    static_cast<size_t>(0), NULL, 0) == 0))
+    {
+        _E("Invalid argument : %s", pkg_name);
+        return FALSE;
+    }
+
+    Try {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTizenAppId(pkgid);
+        _D("appid : %ls", appid.c_str());
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        WrtDB::WrtDatabase::detachFromThread();
+        return FALSE;
+    }
+    WrtDB::WrtDatabase::detachFromThread();
+    return TRUE;
+}
+
+static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
+                                              const char * /*option*/,
+                                              package_manager_pkg_info_t **list,
+                                              int *count)
+{
+    _D("pkg_plugin_get_installed_apps_list() is called");
+
+    package_manager_pkg_info_t *pkg_list = NULL;
+    package_manager_pkg_info_t *pkg_last = NULL;
+
+    WrtDB::WrtDatabase::attachToThreadRO();
+    TizenAppIdList tizenAppIdList = WidgetDAOReadOnly::getTizenAppIdList();
+    *count = 0;
+
+    FOREACH(iterator, tizenAppIdList) {
+        package_manager_pkg_info_t *pkg_info =
+            static_cast<package_manager_pkg_info_t*>
+            (malloc(sizeof(package_manager_pkg_info_t)));
+
+        if (NULL == pkg_list) {
+            pkg_list = pkg_info;
+            pkg_last = pkg_info;
+        } else {
+            pkg_last->next = pkg_info;
+        }
+
+        TizenAppId tzAppid = *iterator;
+        WidgetDAOReadOnly widget(tzAppid);
+        strncpy(pkg_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
+        snprintf(pkg_info->pkg_name, PKG_NAME_STRING_LEN_MAX, "%s",
+                 DPL::ToUTF8String(tzAppid).c_str());
+
+        DPL::OptionalString version = widget.getVersion();
+        if (!!version) {
+            strncpy(pkg_info->version,
+                    DPL::ToUTF8String(*version).c_str(),
+                    PKG_VERSION_STRING_LEN_MAX - 1);
+        }
+
+        (*count)++;
+        pkg_last = pkg_info;
+    }
+    *list = pkg_list;
+    WrtDB::WrtDatabase::detachFromThread();
+
+    return TRUE;
+}
+
+static int pkg_plugin_get_app_detail_info(
+    const char *pkg_name,
+    package_manager_pkg_detail_info_t *
+    pkg_detail_info)
+{
+    _D("pkg_plugin_get_app_detail_info() is called");
+
+    WrtDB::WrtDatabase::attachToThreadRO();
+
+    WrtDB::TizenAppId appid;
+    Try {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTizenAppId(pkgid);
+        _D("appid : %ls", appid.c_str());
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        WrtDB::WrtDatabase::detachFromThread();
+        return FALSE;
+    }
+
+    WidgetDAOReadOnly widget(appid);
+
+    DPL::OptionalString version = widget.getVersion();
+    DPL::OptionalString id = widget.getGUID();
+    DPL::OptionalString locale = widget.getDefaultlocale();
+
+    if (!!version) {
+        strncpy(pkg_detail_info->version,
+                DPL::ToUTF8String(*version).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+    snprintf(pkg_detail_info->pkgid, PKG_NAME_STRING_LEN_MAX, "%s",
+             pkg_name);
+    snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%s",
+             DPL::ToUTF8String(appid).c_str());
+    WidgetLocalizedInfo localizedInfo;
+
+    if (!locale) {
+        _D("locale is NULL");
+        DPL::String languageTag(L"");
+        localizedInfo = widget.getLocalizedInfo(languageTag);
+    } else {
+        localizedInfo = widget.getLocalizedInfo(*locale);
+    }
+    DPL::OptionalString desc(localizedInfo.description);
+
+    if (!!desc) {
+        strncpy(pkg_detail_info->pkg_description,
+                DPL::ToUTF8String(*desc).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+    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 - 1);
+
+    std::string min_version = DPL::ToUTF8String((*widget.getMinimumWacVersion()));
+
+    strncpy(pkg_detail_info->min_platform_version, min_version.c_str(),
+            PKG_VERSION_STRING_LEN_MAX - 1);
+
+    /* 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);
+
+    WrtDB::WrtDatabase::detachFromThread();
+    return TRUE;
+}
+
+int getConfigParserData(const std::string &widgetPath, ConfigParserData& configInfo)
+{
+    const char* CONFIG_XML = "config.xml";
+    const char* WITH_OSP_XML = "res/wgt/config.xml";
+
+    Try {
+        ParserRunner parser;
+
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        // Open config.xml file
+        Try {
+            configFile.reset(zipFile->OpenFile(CONFIG_XML));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
+        }
+
+        // Extract config
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        parser.Parse(&buffer,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(configInfo,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        _E("Failed to open widget package");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        _E("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::CopyFailed)
+    {
+        _E("Failed to extract config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::FileInput::Exception::OpenFailed)
+    {
+        _E("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        _E("Failed to parse config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::SeekFileFailed)
+    {
+        _E("Failed to seek widget archive - corrupted package?");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+char* getIconInfo(const std::string &widgetPath,
+        const std::string &icon_name, int &icon_size)
+{
+    Try {
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> iconFile;
+
+        Try {
+            iconFile.reset(zipFile->OpenFile(icon_name));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            _D("This web app is hybrid web app");
+            std::string hybrid_icon = "res/wgt/" + icon_name;
+            iconFile.reset(zipFile->OpenFile(hybrid_icon));
+        }
+
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(iconFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        icon_size = buffer.Size();
+        char *getBuffer = (char*) calloc(1, (sizeof(char) * icon_size) + 1);
+        buffer.Flatten(getBuffer, buffer.Size());
+        return getBuffer;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        _D("Failed to open widget package");
+        return NULL;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        _D("Not found icon file %s", icon_name.c_str());
+        return NULL;
+    }
+}
+
+char* getIconForLocale(const std::string& bp, const std::string& tag,
+                                     const std::string& icon, int & size)
+{
+    std::string iconPath;
+    if (!tag.empty()) {
+        iconPath += std::string("locales/") + tag;
+    }
+    if (!iconPath.empty()) {
+        iconPath += "/";
+    }
+
+    iconPath += icon;
+    return getIconInfo(bp, iconPath, size);
+}
+
+char* getIcon(const std::string & basepath, const WrtDB::ConfigParserData & config, int & size)
+{
+    const std::list<std::string> defaultIcons{ "icon.svg", "icon.ico", "icon.png", "icon.gif", "icon.jpg" };
+    LanguageTags tagsList =
+        LanguageTagsProviderSingleton::Instance().getLanguageTags();
+
+    char * result = NULL;
+
+    //for each locale tag - searching for icon presence and returning raw data
+    //first found is best as locale tags are ordered
+    FOREACH(tag, tagsList)
+    {
+        FOREACH(icon, config.iconsList)
+        {
+            std::string src = DPL::ToUTF8String(icon->src);
+            result = getIconForLocale(basepath, DPL::ToUTF8String(*tag), src, size);
+            if(result) {
+                return result;
+            }
+        }
+        FOREACH(i, defaultIcons)
+        {
+            result = getIconForLocale(basepath, DPL::ToUTF8String(*tag), *i, size);
+            if(result) {
+                return result;
+            }
+        }
+    }
+    return NULL;
+}
+
+int getWidgetDetailInfoFromPackage(const char* pkgPath,
+        package_manager_pkg_detail_info_t* pkg_detail_info)
+{
+    const std::string widget_path(pkgPath);
+    ConfigParserData configInfo;
+
+    if (FALSE == getConfigParserData(widget_path, configInfo)) {
+        return FALSE;
+    }
+
+    strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
+    if (!!configInfo.tizenPkgId) {
+        strncpy(pkg_detail_info->pkgid,
+                DPL::ToUTF8String(*configInfo.tizenPkgId).c_str(), PKG_TYPE_STRING_LEN_MAX - 1);
+    }
+    if (!!configInfo.tizenAppId) {
+        strncpy(pkg_detail_info->pkg_name,
+                DPL::ToUTF8String(*configInfo.tizenAppId).c_str(),
+                PKG_NAME_STRING_LEN_MAX - 1);
+    }
+    if (!!configInfo.version) {
+        strncpy(pkg_detail_info->version,
+                DPL::ToUTF8String(*configInfo.version).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    DPL::OptionalString name;
+    DPL::OptionalString desc;
+
+    LanguageTags tags = LanguageTagsProviderSingleton::Instance().getLanguageTags();
+
+    auto toLowerCase = [](const DPL::String & r)
+    {
+        DPL::String result;
+        std::transform(r.begin(), r.end(), std::inserter(result, result.begin()), ::tolower);
+        return result;
+    };
+
+    if (!!configInfo.defaultlocale)
+    {
+        Locale & dl = *configInfo.defaultlocale;
+        configInfo.defaultlocale = toLowerCase(dl);
+    }
+
+    bool found = false;
+    FOREACH(tag, tags)
+    {
+        *tag = toLowerCase(*tag);
+        FOREACH(localizedData, configInfo.localizedDataSet)
+        {
+            Locale i = localizedData->first;
+            i = toLowerCase(i);
+
+            if (!!configInfo.defaultlocale && *configInfo.defaultlocale == i)
+            {
+                name = localizedData->second.name;
+                desc = localizedData->second.description;
+            }
+            if (*tag == i)
+            {
+                name = localizedData->second.name;
+                desc = localizedData->second.description;
+                found = true;
+                break;
+            }
+        }
+        if(found) break;
+    }
+
+    if (!!name) {
+        strncpy(pkg_detail_info->label, DPL::ToUTF8String(*name).c_str(),
+                PKG_LABEL_STRING_LEN_MAX - 1);
+    }
+
+    if (!!desc) {
+        strncpy(pkg_detail_info->pkg_description,
+                DPL::ToUTF8String(*desc).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    if (!!configInfo.tizenMinVersionRequired) {
+        strncpy(pkg_detail_info->min_platform_version,
+                DPL::ToUTF8String(*configInfo.tizenMinVersionRequired).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    if (!!configInfo.authorName) {
+        strncpy(pkg_detail_info->author,
+                DPL::ToUTF8String(*configInfo.authorName).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+
+    pkg_detail_info->privilege_list = NULL;
+    FOREACH(it, configInfo.featuresList) {
+        std::string featureInfo =  DPL::ToUTF8String(it->name);
+        _D("privilege : %s", featureInfo.c_str());
+        int length = featureInfo.size();
+        char *privilege = (char*) calloc(1, (sizeof(char) * (length + 1)));
+        snprintf(privilege, length + 1, "%s", featureInfo.c_str());
+        pkg_detail_info->privilege_list =
+            g_list_append(pkg_detail_info->privilege_list, privilege);
+    }
+
+    char* icon_buf = getIcon(widget_path, configInfo, pkg_detail_info->icon_size);
+
+    if (icon_buf) {
+        _D("icon size : %d", pkg_detail_info->icon_size);
+        pkg_detail_info->icon_buf = icon_buf;
+    } else {
+        _D("No icon");
+        pkg_detail_info->icon_size = 0;
+        pkg_detail_info->icon_buf = NULL;
+    }
+
+    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)
+{
+    _D("pkg_plugin_get_app_detail_info_from_package() is called");
+    return getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+}
+
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path)
+{
+    _D("pkgmgr_client_check_pkginfo_from_file() is called");
+    package_manager_pkg_detail_info_t *pkg_detail_info;
+    pkg_detail_info = (package_manager_pkg_detail_info_t*)malloc(
+            sizeof(package_manager_pkg_detail_info_t));
+    int ret = getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+    if (FALSE == ret) {
+        _E("Failed to get package detail info ");
+        free(pkg_detail_info);
+        return NULL;
+    }
+    return reinterpret_cast<pkgmgr_info*>(pkg_detail_info);
+}
+
+__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_wearable/pkg-manager/pkgmgr_signal.cpp b/src_wearable/pkg-manager/pkgmgr_signal.cpp
new file mode 100644 (file)
index 0000000..a5f2383
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Yunchan Cho (yunchan.cho@samsung.com)
+ * @version     0.1
+ * @brief
+ */
+
+#include <dpl/lexical_cast.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <pkgmgr_installer.h>
+#include <pkg-manager/pkgmgr_signal.h>
+#include <installer_log.h>
+
+namespace {
+// package type sent in every signal
+const char PKGMGR_WEBAPP_TYPE[] = "wgt";
+
+// notification about opoeration start
+const char PKGMGR_START_KEY[] = "start";
+
+// value for new installation
+const char PKGMGR_START_INSTALL[] = "install";
+
+// value for update installation
+const char PKGMGR_START_UPDATE[] = "update";
+
+// value for uninstallation
+const char PKGMGR_START_UNINSTALL[] = "uninstall";
+
+// notification about progress of installation with percentage number
+const char PKGMGR_PROGRESS_KEY[] = "install_percent";
+
+// notification about icon path for installation frontend
+const char PKGMGR_ICON_PATH[] = "icon_path";
+
+// notification about error before end with given error code
+// (currently, same as backend exit status)
+const char PKGMGR_ERROR[] = "error";
+
+// notification about end of installation with status
+const char PKGMGR_END_KEY[] = "end";
+
+// success value of end of installation
+const char PKGMGR_END_SUCCESS[] = "ok";
+
+// failure value of end of installation
+const char PKGMGR_END_FAILURE[] = "fail";
+}
+
+namespace PackageManager {
+PkgmgrSignal::PkgmgrSignal() :
+    m_initialized(false),
+    m_handle(NULL),
+    m_reqType(RequestType::UNSUPPORTED),
+    m_percent(0)
+{}
+
+PkgmgrSignal::~PkgmgrSignal()
+{
+    deinitialize();
+}
+
+bool PkgmgrSignal::initialize(int argc, char* argv[])
+{
+    if (m_handle) {
+        _D("Release already allocated pkgmgr handle");
+        pkgmgr_installer_free(m_handle);
+        m_handle = NULL;
+    }
+
+    m_handle = pkgmgr_installer_new();
+    if (!m_handle) {
+        _E("Fail to get pkgmgr installer handle");
+        return false;
+    }
+
+    // set information from pkgmgr
+    if (!pkgmgr_installer_receive_request(
+            m_handle, argc, argv))
+    {
+        auto pkgmgrtype = pkgmgr_installer_get_request_type(m_handle);
+        switch(pkgmgrtype)
+        {
+            case PKGMGR_REQ_INSTALL:
+                m_reqType = RequestType::INSTALL;
+                break;
+            case PKGMGR_REQ_UNINSTALL:
+                m_reqType = RequestType::UNINSTALL;
+                break;
+            case PKGMGR_REQ_REINSTALL:
+                m_reqType = RequestType::REINSTALL;
+                break;
+            default:
+                m_reqType = RequestType::UNSUPPORTED;
+                break;
+        }
+
+        if (m_reqType == RequestType::UNSUPPORTED)
+        {
+            _E("Fail to get request type of pkgmgr");
+            pkgmgr_installer_free(m_handle);
+            m_handle = NULL;
+            return false;
+        }
+        const char *callerId = pkgmgr_installer_get_caller_pkgid(m_handle);
+        if(callerId)
+            m_callerId = callerId;
+
+    } else {
+        _E("Fail to get information of pkgmgr's request");
+        pkgmgr_installer_free(m_handle);
+        m_handle = NULL;
+        return false;
+    }
+
+    m_type = PKGMGR_WEBAPP_TYPE;
+    m_initialized = true;
+    return true;
+}
+
+bool PkgmgrSignal::deinitialize()
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+        return false;
+    }
+
+    if (!m_recoveryFile.empty() && (0 != unlink(m_recoveryFile.c_str()))) {
+        _E("Failed to remove %s", m_recoveryFile.c_str());
+    }
+
+    if (m_handle) {
+        pkgmgr_installer_free(m_handle);
+    }
+
+    m_handle = NULL;
+    m_initialized = false;
+    return true;
+}
+
+bool PkgmgrSignal::setPkgname(const std::string& name)
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+        return false;
+    }
+
+    if (name.empty()) {
+        _E("name is empty");
+        return false;
+    }
+
+    m_pkgname = name;
+    _D("Success to set tizen package name: %s", m_pkgname.c_str());
+    setRecoveryFile();
+
+    return true;
+}
+
+void PkgmgrSignal::setRecoveryFile()
+{
+    std::string filePath = WrtDB::GlobalConfig::GetTempInstallInfoPath();
+    filePath += "/" + m_pkgname;
+
+    m_recoveryFile = filePath;
+    _D("SetRecoveryFile... %s", filePath.c_str());
+    if (access(filePath.c_str(), F_OK) != 0) {
+        FILE *file = fopen(filePath.c_str(), "w");
+        if (file != NULL) {
+            fclose(file);
+        }
+    } else {
+        _D("Recovery File : %s is already exist", filePath.c_str());
+    }
+}
+
+bool PkgmgrSignal::startJob(Jobs::InstallationType type)
+{
+    switch(type)
+    {
+        case Jobs::InstallationType::NewInstallation:
+            sendSignal(PKGMGR_START_KEY, PKGMGR_START_INSTALL);
+            break;
+        case Jobs::InstallationType::UpdateInstallation:
+            sendSignal(PKGMGR_START_KEY, PKGMGR_START_UPDATE);
+            break;
+        case Jobs::InstallationType::Uninstallation:
+            sendSignal(PKGMGR_START_KEY, PKGMGR_START_UNINSTALL);
+            break;
+        default:
+            _E("Trying to send unknown installation type to pkgmgr");
+            return false;
+    }
+    return true;
+}
+
+bool PkgmgrSignal::endJob(Jobs::Exceptions::Type ecode)
+{
+    if(ecode == Jobs::Exceptions::Type::Success)
+    {
+        return sendSignal(PKGMGR_END_KEY, PKGMGR_END_SUCCESS);
+    }
+    else
+    {
+        sendSignal(PKGMGR_ERROR, DPL::lexical_cast<std::string>(ecode));
+        return sendSignal(PKGMGR_END_KEY, PKGMGR_END_FAILURE);
+    }
+}
+
+bool PkgmgrSignal::sendProgress(int percent)
+{
+    if (m_percent == percent) {
+        return true;
+    }
+
+    m_percent = percent;
+    return sendSignal(PKGMGR_PROGRESS_KEY, DPL::lexical_cast<std::string>(percent));
+}
+
+bool PkgmgrSignal::sendIconPath(const std::string & iconpath)
+{
+    return sendSignal(PKGMGR_ICON_PATH, iconpath);
+}
+
+bool PkgmgrSignal::sendSignal(const std::string& key,
+                              const std::string& value) const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+        return false;
+    }
+
+    if (key.empty() || value.empty()) {
+        _D("key or value is empty");
+        return false;
+    }
+
+    if (m_handle == NULL || m_type.empty()) {
+        _E("Some data of PkgmgrSignal is empty");
+        return false;
+    }
+
+    // send pkgmgr signal
+    if (pkgmgr_installer_send_signal(
+            m_handle, m_type.c_str(), m_pkgname.c_str(),
+            key.c_str(), value.c_str()))
+    {
+        _E("Fail to send pkgmgr signal");
+        return false;
+    }
+
+    _D("Success to send pkgmgr signal: %s - %s", key.c_str(), value.c_str());
+    return true;
+}
+
+std::string PkgmgrSignal::getPkgname() const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+    }
+
+    return m_pkgname;
+}
+
+PkgmgrSignal::RequestType PkgmgrSignal::getRequestedType() const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+    }
+
+    return m_reqType;
+}
+
+std::string PkgmgrSignal::getCallerId() const
+{
+    if (!m_initialized) {
+        _E("PkgmgrSingal not yet intialized");
+    }
+
+    return m_callerId;
+}
+} // PackageManager
diff --git a/src_wearable/pkg-manager/pkgmgr_signal.h b/src_wearable/pkg-manager/pkgmgr_signal.h
new file mode 100644 (file)
index 0000000..26ce559
--- /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.
+ */
+/*
+ * @author      Yunchan Cho (yunchan.cho@samsung.com)
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     0.2
+ * @brief
+ */
+
+#ifndef WRT_PKGMGR_SIGNAL_H_
+#define WRT_PKGMGR_SIGNAL_H_
+
+#include <pkg-manager/pkgmgr_signal_interface.h>
+
+struct pkgmgr_installer;
+
+namespace PackageManager {
+
+class PkgmgrSignal : public IPkgmgrSignal
+{
+public:
+    enum class RequestType
+    {
+        UNSUPPORTED,
+        INSTALL,
+        UNINSTALL,
+        REINSTALL
+    };
+
+    bool initialize(int argc, char* argv[]);
+    bool deinitialize();
+    bool setPkgname(const std::string& name);
+    std::string getPkgname() const;
+    RequestType getRequestedType() const;
+    std::string getCallerId() const;
+
+    bool startJob(Jobs::InstallationType type);
+    bool endJob(Jobs::Exceptions::Type ecode);
+    bool sendProgress(int percent);
+    bool sendIconPath(const std::string & iconpath);
+    void setRecoveryFile();
+
+    PkgmgrSignal();
+    virtual ~PkgmgrSignal();
+
+protected:
+    bool sendSignal(const std::string& key, const std::string& value) const;
+
+private:
+    bool m_initialized;
+    pkgmgr_installer* m_handle;
+    std::string m_type;
+    std::string m_pkgname;
+    RequestType m_reqType;
+    std::string m_callerId;
+    int m_percent;
+    std::string m_recoveryFile;
+};
+} // PackageManager
+
+#endif // WRT_PKGMGR_SIGNAL_H_
+
diff --git a/src_wearable/pkg-manager/pkgmgr_signal_dummy.h b/src_wearable/pkg-manager/pkgmgr_signal_dummy.h
new file mode 100644 (file)
index 0000000..42b0aa4
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+/*
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     0.1
+ * @brief       Dummy version of PkgmgrSignal.
+ */
+
+#ifndef WRT_PKGMGR_SIGNAL_DUMMY_H_
+#define WRT_PKGMGR_SIGNAL_DUMMY_H_
+
+#include <pkg-manager/pkgmgr_signal_interface.h>
+
+#include <dpl/availability.h>
+
+namespace PackageManager {
+class PkgmgrSignalDummy : public IPkgmgrSignal
+{
+  public:
+    PkgmgrSignalDummy()
+    {}
+
+    virtual ~PkgmgrSignalDummy()
+    {}
+
+    bool setPkgname(const std::string& /*name*/)
+    {
+        return false;
+    }
+
+    std::string getPkgname() const
+    {
+        return "";
+    }
+
+    std::string getCallerId() const
+    {
+        return "";
+    }
+
+    bool startJob(Jobs::InstallationType type DPL_UNUSED)
+    {
+        return false;
+    }
+
+    bool endJob(Jobs::Exceptions::Type ecode DPL_UNUSED)
+    {
+        return false;
+    }
+
+    bool sendProgress(int percent DPL_UNUSED)
+    {
+        return false;
+    }
+
+    bool sendIconPath(const std::string & iconpath DPL_UNUSED)
+    {
+        return false;
+    }
+};
+} // PkgmgrSignalDummy
+
+#endif // WRT_PKGMGR_SIGNAL_DUMMY_H_
diff --git a/src_wearable/pkg-manager/pkgmgr_signal_interface.h b/src_wearable/pkg-manager/pkgmgr_signal_interface.h
new file mode 100644 (file)
index 0000000..1e38a17
--- /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.
+ */
+/*
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     0.1
+ * @brief       Interface for PkgmgrSignal.
+ */
+
+#ifndef WRT_PKGMGR_SIGNAL_INTERFACE_H_
+#define WRT_PKGMGR_SIGNAL_INTERFACE_H_
+
+#include <string>
+
+#include <job_types.h>
+#include <job_exception_error.h>
+
+namespace PackageManager {
+class IPkgmgrSignal
+{
+  public:
+    virtual bool setPkgname(const std::string& name) = 0;
+    virtual std::string getPkgname() const = 0;
+    virtual std::string getCallerId() const = 0;
+
+    virtual bool startJob(Jobs::InstallationType type) = 0;
+    virtual bool endJob(Jobs::Exceptions::Type ecode) = 0;
+    virtual bool sendProgress(int percent) = 0;
+    virtual bool sendIconPath(const std::string & iconpath) = 0;
+    virtual ~IPkgmgrSignal(){}
+};
+} // IPkgmgrSignal
+
+#endif // WRT_PKGMGR_SIGNAL_INTERFACE_H_
diff --git a/src_wearable/wrt-installer/CMakeLists.txt b/src_wearable/wrt-installer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..533bcfa
--- /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   Lukasz Wrzosek (l.wrzosek@samsung.com)
+# @version     1.0
+#
+
+SET(WRT_INSTALLER_DIR
+    ${INSTALLER_SRC_DIR}/wrt-installer
+    )
+
+SET(PKG_MANAGER_DIR
+    ${INSTALLER_SRC_DIR}/pkg-manager
+    )
+
+SET(WRT_INSTALLER_SOURCES
+    ${WRT_INSTALLER_DIR}/wrt-installer.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}/command_parser.cpp
+    ${PKG_MANAGER_DIR}/pkgmgr_signal.cpp
+)
+
+PKG_CHECK_MODULES(WRT_INSTALLER_DEPS
+    pkgmgr-installer
+    libpcrecpp
+    pkgmgr-info
+    pkgmgr
+    security-install
+    wrt-commons-i18n-dao-ro
+    capi-system-power
+    REQUIRED)
+
+INCLUDE_DIRECTORIES(
+    ${PKG_MANAGER_DIR}
+    ${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(${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"
+    BUILD_WITH_INSTALL_RPATH ON
+    INSTALL_RPATH_USE_LINK_PATH ON
+)
+
+INSTALL(TARGETS ${TARGET_INSTALLER} DESTINATION bin)
diff --git a/src_wearable/wrt-installer/command_parser.cpp b/src_wearable/wrt-installer/command_parser.cpp
new file mode 100644 (file)
index 0000000..2459596
--- /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.
+ */
+/**
+ * @file    command_parser.cpp
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @brief   Implementation file for OptionParser.
+ */
+
+#include <dpl/string.h>
+#include <dpl/errno_string.h>
+#include <installer_log.h>
+#include "command_parser.h"
+
+namespace {
+typedef std::pair<std::string, std::string> DataPair;
+
+const char* const KEY_OP = "op";
+const char* const KEY_PATH = "path";
+const char* const KEY_REMOVABLE = "removable";
+}
+
+bool CommandParser::CscCommandParser(const std::string& arg, CscOption &option)
+{
+    using namespace Command;
+    // path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true
+    // parsing CSC configuration string
+    _D("CscCommandParser");
+    if (arg.empty()) {
+        return false;
+    }
+    DataMap cmdMap = ArgumentsParser(arg);
+
+    DataMap::iterator it;
+    it = cmdMap.find(KEY_OP);
+    if (it == cmdMap.end()) {
+        return false;
+    }
+
+    if (it->second == VALUE_INSTALL) {
+        _D("operation = %s", it->second.c_str());
+        option.operation = VALUE_INSTALL;
+        it = cmdMap.find(KEY_PATH);
+        if (it == cmdMap.end()) {
+            return false;
+        }
+        option.path = it->second;
+        _D("path      = %s", option.path.c_str());
+
+        it = cmdMap.find(KEY_REMOVABLE);
+        if (it == cmdMap.end()) {
+            return false;
+        }
+
+        option.removable = true;
+        if (0 == it->second.compare(VALUE_FALSE)) {
+            option.removable = false;
+        }
+    } else if (it->second == VALUE_UNINSTALL) {
+        _D("operation = %s", it->second.c_str());
+        // uninstall command isn't confirmed yet
+        it = cmdMap.find(KEY_PATH);
+        if (it == cmdMap.end()) {
+            return false;
+        }
+        option.path = it->second;
+        _D("operation = uninstall");
+        _D("path      = %s", option.path.c_str());
+    } else {
+        _E("Unknown operation : %s", it->second.c_str());
+        _D("operation = %s", it->second.c_str());
+        return false;
+    }
+
+    return true;
+}
+
+bool CommandParser::FotaCommandParser(const std::string& arg, FotaOption
+        &option)
+{
+    using namespace Command;
+    // path=pkgid:op=install
+    _D("FotaCommandParser");
+    DataMap cmdMap = ArgumentsParser(arg);
+
+    DataMap::iterator it;
+    it = cmdMap.find(KEY_OP);
+    if (it == cmdMap.end()) {
+        return false;
+    }
+    option.operation = it->second;
+
+    it = cmdMap.find(KEY_PATH);
+    if (it == cmdMap.end()) {
+        return false;
+    }
+
+    option.pkgId = it->second;
+    _D("Fota : package_id [%s], operaion [%s]", option.pkgId.c_str(),
+            option.operation.c_str());
+
+    return true;
+}
+
+CommandParser::DataMap CommandParser::ArgumentsParser(const std::string& arg)
+{
+    DataMap result;
+
+    if (arg.empty()) {
+        _D("Input argument is empty");
+        return result;
+    }
+
+    const char* ptr = strtok(const_cast<char*>(arg.c_str()),":");
+    while (ptr != NULL) {
+        std::string string = ptr;
+        ptr = strtok (NULL, ":");
+        size_t pos = string.find('=');
+        if (pos == std::string::npos) {
+            continue;
+        }
+        result.insert(
+                DataPair(string.substr(0, pos),
+                    string.substr(pos+1)));
+    }
+
+    return result;
+}
diff --git a/src_wearable/wrt-installer/command_parser.h b/src_wearable/wrt-installer/command_parser.h
new file mode 100755 (executable)
index 0000000..49527f9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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    command_parser.h
+ * @author  Soyoung Kim (sy037.kim@samsung.com)
+ * @brief   Header file for Command parser
+ */
+
+#ifndef WRT_INSTALLER_SRC_WRT_INSTALLER_COMMAND_PARSER_H_
+#define WRT_INSTALLER_SRC_WRT_INSTALLER_COMMAND_PARSER_H_
+
+#include <string>
+#include <map>
+#include <utility>
+
+namespace Command {
+const char* const VALUE_INSTALL = "install";
+const char* const VALUE_UNINSTALL = "uninstall";
+const char* const VALUE_UPGRADE = "upgrade";
+const char* const VALUE_UPDATE = "update";
+const char* const VALUE_TRUE = "true";
+const char* const VALUE_FALSE = "false";
+}
+
+class CommandParser
+{
+  typedef std::map<std::string, std::string> DataMap;
+
+  public:
+    struct CscOption {
+        std::string path;
+        std::string operation;
+        bool removable;
+    };
+
+    struct FotaOption {
+        std::string pkgId;
+        std::string operation;
+    };
+
+    static bool CscCommandParser(const std::string& arg, CscOption &option);
+    static bool FotaCommandParser(const std::string& arg, FotaOption &option);
+
+  private:
+    static DataMap ArgumentsParser(const std::string& arg);
+};
+
+#endif
diff --git a/src_wearable/wrt-installer/installer_callbacks_translate.cpp b/src_wearable/wrt-installer/installer_callbacks_translate.cpp
new file mode 100644 (file)
index 0000000..ca52dd6
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * 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/assert.h>
+#include <installer_log.h>
+
+namespace InstallerCallbacksTranslate {
+
+// callback for finished install
+void installFinishedCallback(void *userParam,
+                             std::string tizenId,
+                             Jobs::Exceptions::Type status)
+{
+    Assert(userParam != NULL);
+
+    StatusCallbackStruct *apiStr =
+        static_cast<StatusCallbackStruct*>(userParam);
+
+    if (apiStr->status_callback) {
+        // Translate error
+        WrtErrStatus errorStatus;
+
+        switch (status) {
+        case Jobs::Exceptions::Success:
+            errorStatus = WRT_SUCCESS;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageLowerVersion:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageExecutableNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_EXCUTABLE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorManifestNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorManifestInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_MANIFEST_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorConfigNotFound:
+            errorStatus = WRT_INSTALLER_CONFIG_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorConfigInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_CONFIG_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorSignatureNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorSignatureInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_SIGNATURE_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorSignatureVerificationFailed:
+            errorStatus = WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorRootCertificateNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorCertificationInvaid:
+            errorStatus = WRT_INSTALLER_ERROR_CERTIFICATION_INVAID;
+            break;
+
+        case
+            Jobs::Exceptions::ErrorCertificateChainVerificationFailed:
+            errorStatus =
+            WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorCertificateExpired:
+            errorStatus = WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED;
+            break;
+
+        case Jobs::Exceptions::ErrorInvalidPrivilege:
+            errorStatus = WRT_INSTALLER_ERROR_INVALID_PRIVILEGE;
+            break;
+
+        case Jobs::Exceptions::ErrorPrivilegeLevelViolation:
+            errorStatus = WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION;
+            break;
+
+        case Jobs::Exceptions::ErrorMenuIconNotFound:
+            errorStatus = WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND;
+            break;
+
+        case Jobs::Exceptions::ErrorFatalError:
+            errorStatus = WRT_INSTALLER_ERROR_FATAL_ERROR;
+            break;
+
+        case Jobs::Exceptions::ErrorOutOfStorage:
+            errorStatus = WRT_INSTALLER_ERROR_OUT_OF_STORAGE;
+            break;
+
+        case Jobs::Exceptions::ErrorOutOfMemory:
+            errorStatus = WRT_INSTALLER_ERROR_OUT_OF_MEMORY;
+            break;
+
+        case Jobs::Exceptions::ErrorArgumentInvalid:
+            errorStatus = WRT_INSTALLER_ERROR_ARGUMENT_INVALID;
+            break;
+
+        case Jobs::Exceptions::ErrorPackageAlreadyInstalled:
+            errorStatus = WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED;
+            break;
+
+        case Jobs::Exceptions::ErrorAceCheckFailed:
+            errorStatus = WRT_INSTALLER_ERROR_ACE_CHECK_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorManifestCreateFailed:
+            errorStatus = WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorEncryptionFailed:
+            errorStatus = WRT_INSTALLER_ERROR_ENCRYPTION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorInstallOspServcie:
+            errorStatus = WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE;
+            break;
+
+        default:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+        }
+
+        // Callback
+        apiStr->status_callback(tizenId, errorStatus, apiStr->userdata);
+    } else {
+        _D("installFinishedCallback: No callback");
+    }
+}
+
+// callback for finished install
+void uninstallFinishedCallback(void *userParam,
+                               std::string tizenId,
+                               Jobs::Exceptions::Type status)
+{
+    Assert(userParam != NULL);
+
+    StatusCallbackStruct *apiStr =
+        static_cast<StatusCallbackStruct*>(userParam);
+
+    if (apiStr->status_callback) {
+        // Translate error
+        WrtErrStatus errorStatus;
+
+        switch (status) {
+        case Jobs::Exceptions::Success:
+            errorStatus = WRT_SUCCESS;
+            break;
+
+        case Jobs::Exceptions::ErrorWidgetUninstallationFailed:
+            errorStatus = WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED;
+            break;
+
+        case Jobs::Exceptions::ErrorUnknown:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+
+        default:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+        }
+
+        // Callback
+        apiStr->status_callback(tizenId, errorStatus, apiStr->userdata);
+    } else {
+        _D("uninstallFinishedCallback: No callback");
+    }
+}
+
+void pluginInstallFinishedCallback(void *userParam,
+                                   Jobs::Exceptions::Type status)
+{
+    Assert(userParam);
+
+    PluginStatusCallbackStruct *apiStr =
+        static_cast<PluginStatusCallbackStruct*>(userParam);
+
+    if (apiStr->statusCallback) {
+        // Translate error
+        WrtErrStatus errorStatus;
+
+        switch (status) {
+        case Jobs::Exceptions::Success:
+            errorStatus = WRT_SUCCESS;
+            break;
+        case Jobs::Exceptions::ErrorPluginInstallationFailed:
+            errorStatus = WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED;
+            break;
+        default:
+            errorStatus = WRT_INSTALLER_ERROR_UNKNOWN;
+            break;
+        }
+
+        apiStr->statusCallback(errorStatus, apiStr->userdata);
+    } else {
+        _D("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
+        _D("Entered %2.0f%% %s", percent, description.c_str());
+        apiStr->progress_callback(static_cast<float>(percent),
+                                  description.c_str(),
+                                  apiStr->userdata);
+    } else {
+        _D("installProgressCallback: ignoring NULL callback pointer");
+    }
+}
+} //namespace
+
diff --git a/src_wearable/wrt-installer/installer_callbacks_translate.h b/src_wearable/wrt-installer/installer_callbacks_translate.h
new file mode 100644 (file)
index 0000000..f20ecc2
--- /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.
+ */
+/**
+ * @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 <string>
+
+#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>
+#include <wrt_type.h>
+#include <wrt_install_mode.h>
+#include <pkgmgr_signal_interface.h>
+
+typedef void (*WrtInstallerInitCallback)(WrtErrStatus status,
+                                         void *data);
+typedef void (*WrtPluginInstallerStatusCallback)(WrtErrStatus status,
+                                                 void *data);
+typedef void (*WrtInstallerStatusCallback)(std::string tizenId,
+                                           WrtErrStatus status,
+                                           void *data);
+typedef void (*WrtProgressCallback)(float percent,
+                                    const char *description,
+                                    void *data);
+
+
+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 installFinishedCallback(void *userParam,
+                             std::string tizenId,
+                             Jobs::Exceptions::Type status);
+
+void uninstallFinishedCallback(void *userParam,
+                               std::string tizenId,
+                               Jobs::Exceptions::Type status);
+
+void pluginInstallFinishedCallback(void *userParam,
+                                   Jobs::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_wearable/wrt-installer/installer_main_thread.cpp b/src_wearable/wrt-installer/installer_main_thread.cpp
new file mode 100644 (file)
index 0000000..b398d3c
--- /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       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 <vcore/VCore.h>
+#include <dpl/singleton_impl.h>
+#include <dpl/assert.h>
+#include <installer_controller.h>
+#include <ace_api_install.h>
+
+IMPLEMENT_SINGLETON(InstallerMainThread)
+
+using namespace WrtDB;
+
+InstallerMainThread::InstallerMainThread() : m_attached(false) {}
+
+InstallerMainThread::~InstallerMainThread()
+{
+    Assert(!m_attached);
+}
+
+void InstallerMainThread::AttachDatabases()
+{
+    Assert(!m_attached);
+    // Attach databases
+    ValidationCore::AttachToThreadRW();
+    ace_return_t ret = ace_install_initialize();
+    Assert(ACE_OK == ret); // to be changed to exception in the future
+    WrtDB::WrtDatabase::attachToThreadRW();
+    m_attached = true;
+}
+
+void InstallerMainThread::DetachDatabases()
+{
+    Assert(m_attached);
+    m_attached = false;
+    // Detach databases
+    ValidationCore::DetachFromThread();
+    ace_return_t ret = ace_install_shutdown();
+    Assert(ACE_OK == ret); // to be changed to exception in the future
+    WrtDB::WrtDatabase::detachFromThread();
+}
+
+void InstallerMainThread::TouchArchitecture()
+{
+    // Touch controller
+    Logic::InstallerControllerSingleton::Instance().Touch();
+}
+
+void InstallerMainThread::TouchArchitectureOnlyInstaller()
+{
+    // Touch controller
+    Logic::InstallerControllerSingleton::Instance().Touch();
+}
diff --git a/src_wearable/wrt-installer/installer_main_thread.h b/src_wearable/wrt-installer/installer_main_thread.h
new file mode 100644 (file)
index 0000000..bd70b16
--- /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       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_wearable/wrt-installer/language_subtag_rst_tree.cpp b/src_wearable/wrt-installer/language_subtag_rst_tree.cpp
new file mode 100644 (file)
index 0000000..a2bfaf5
--- /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    language_subtag_rst_tree.cpp
+ * @author  Lukasz Wrzosek (l.wrzosek@samsung.com)
+ * @version 1.0
+ */
+#include <language_subtag_rst_tree.h>
+#include <dpl/db/orm.h>
+#include <dpl/string.h>
+#include <dpl/scope_guard.h>
+#include <wrt-commons/i18n-dao-ro/i18n_dao_read_only.h>
+#include <wrt-commons/i18n-dao-ro/i18n_database.h>
+#include <iterator>
+#include <vector>
+#include <ctype.h>
+#include <dpl/singleton_impl.h>
+#include <installer_log.h>
+
+IMPLEMENT_SINGLETON(LanguageSubtagRstTree)
+
+namespace I18nDAOReadOnly = I18n::DB::I18nDAOReadOnly;
+
+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;
+    }
+
+    I18n::DB::Interface::attachDatabaseRO();
+    DPL_SCOPE_EXIT()
+    {
+        I18n::DB::Interface::detachDatabase();
+    };
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_LANGUAGE))
+    {
+        ++token;
+    }
+    else
+    {
+        return false;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_EXTLANG))
+    {
+        ++token;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_SCRIPT))
+    {
+        ++token;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    if (I18nDAOReadOnly::IsValidSubTag(*token, RECORD_TYPE_REGION))
+    {
+        ++token;
+    }
+
+    if (token == parts.end())
+    {
+        return true;
+    }
+
+    while (token != parts.end())
+    {
+        if (I18nDAOReadOnly::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) { \
+        _D("Good validate status for lang: %s", str); \
+    } else { \
+        _E("Wrong validate status for lang: %s, should be %d", str, 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_wearable/wrt-installer/language_subtag_rst_tree.h b/src_wearable/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_wearable/wrt-installer/plugin_utils.cpp b/src_wearable/wrt-installer/plugin_utils.cpp
new file mode 100644 (file)
index 0000000..cabda19
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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 <unistd.h>
+#include "plugin_utils.h"
+#include <dpl/exception.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <sys/file.h>
+#include <installer_log.h>
+
+using namespace WrtDB;
+
+namespace PluginUtils {
+const char* PLUGIN_INSTALL_LOCK_FILE = "/tmp/.wrt_plugin_install_lock";
+
+static int s_plugin_install_lock_fd = -1;
+
+bool lockPluginInstallation(bool isPreload)
+{
+    if (isPreload) {
+        fprintf(stderr, "Skip create lock file.. \n");
+        return true;
+    }
+
+    int ret = 0;
+
+    _D("Try to lock for plugins installation.");
+
+    s_plugin_install_lock_fd =
+        open(PLUGIN_INSTALL_LOCK_FILE, O_RDONLY | O_CREAT, 0666);
+
+    if (s_plugin_install_lock_fd == -1) {
+        _E("Lock file open failed!");
+
+        return false;
+    }
+
+    ret = flock(s_plugin_install_lock_fd, LOCK_EX); //lock with waiting
+
+    if (ret == -1) {
+        _E("Lock failed!");
+
+        close(s_plugin_install_lock_fd);
+        s_plugin_install_lock_fd = -1;
+
+        return false;
+    }
+
+    return true;
+}
+
+bool unlockPluginInstallation(bool isPreload)
+{
+    _D("Unlock for plugins installation.");
+    if (isPreload) {
+        fprintf(stderr, "Skip plugin unlock.. \n");
+        return true;
+    }
+
+    if (s_plugin_install_lock_fd != -1) {
+        int ret = 0;
+
+        ret = flock(s_plugin_install_lock_fd, LOCK_UN); //unlock
+
+        if (ret == -1) {
+            _E("Unlock failed!");
+        }
+
+        close(s_plugin_install_lock_fd);
+        s_plugin_install_lock_fd = -1;
+
+        return true;
+    } else {
+        _E("Lock file was not created!");
+    }
+
+    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:
+        _W("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_wearable/wrt-installer/plugin_utils.h b/src_wearable/wrt-installer/plugin_utils.h
new file mode 100644 (file)
index 0000000..8659f20
--- /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    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 isPreload);
+bool unlockPluginInstallation(bool isPreload);
+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_wearable/wrt-installer/wrt-installer.cpp b/src_wearable/wrt-installer/wrt-installer.cpp
new file mode 100755 (executable)
index 0000000..9fc4df6
--- /dev/null
@@ -0,0 +1,1497 @@
+/*
+ * 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 <cstring>
+#include <map>
+
+#include <power.h>
+#include <dirent.h>
+#include <sys/resource.h>
+
+#include <libxml/parser.h>
+#include <dpl/log/log.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/binary_queue.h>
+#include <dpl/copy.h>
+#include <dpl/errno_string.h>
+#include <dpl/localization/w3c_file_localization.h>
+#include <dpl/optional_typedefs.h>
+#include <dpl/utils/widget_version.h>
+#include <dpl/utils/wrt_global_settings.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/zip_input.h>
+
+#include <wrt-commons/i18n-dao-ro/i18n_database.h>
+
+#include <vcore/VCore.h>
+
+#include <Elementary.h>
+
+#include <installer_callbacks_translate.h>
+#include <installer_controller.h>
+#include <installer_log.h>
+#include <installer_main_thread.h>
+#include <language_subtag_rst_tree.h>
+#include <parser_runner.h>
+#include <pkg-manager/pkgmgr_signal_dummy.h>
+#include <pkgmgr-info.h>
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <wrt_install_mode.h>
+#include <command_parser.h>
+
+using namespace WrtDB;
+
+namespace { // anonymous
+const char * const PKGMGR_INSTALL_MSG = "Install widget";
+const char * const PKGMGR_UNINSTALL_MSG = "Uninstall widget";
+
+const char * const CONFIG_XML = "config.xml";
+const char * const HYBRID_CONFIG_XML = "res/wgt/config.xml";
+
+const unsigned int NOFILE_CNT_FOR_INSTALLER = 9999;
+
+struct free_deleter
+{
+    void operator()(void* x)
+    {
+        free(x);
+    }
+};
+
+struct PluginInstallerData
+{
+    void* wrtInstaller;
+    std::string pluginPath;
+};
+
+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);
+    }
+}
+
+bool checkPath(const std::string& path)
+{
+    struct stat st;
+    if (0 == stat(path.c_str(), &st) && S_ISDIR(st.st_mode)) {
+        return true;
+    }
+    _E("Cannot access directory [ %s ]", path.c_str());
+    return false;
+}
+
+bool checkPaths()
+{
+    bool if_ok = true;
+
+    if_ok &= (checkPath(cutOffFileName(GlobalConfig::GetWrtDatabaseFilePath())));
+    if_ok &= (checkPath(GlobalConfig::GetDevicePluginPath()));
+    if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath()));
+    if_ok &= (checkPath(GlobalConfig::GetUserPreloadedWidgetPath()));
+
+    return if_ok;
+}
+
+} // namespace anonymous
+
+WrtInstaller::WrtInstaller(int argc, char **argv) :
+    Application(argc, argv, "backend", false),
+    DPL::TaskDecl<WrtInstaller>(this),
+    m_packagePath(),
+    m_initialized(false),
+    m_numPluginsToInstall(0),
+    m_totalPlugins(0),
+    m_returnStatus(-1),
+    m_sendPkgSig(false),
+    m_startupPluginInstallation(false)
+{
+    Touch();
+    _D("App Created");
+}
+
+WrtInstaller::~WrtInstaller()
+{
+    _D("App Finished");
+}
+
+int WrtInstaller::getReturnStatus() const
+{
+    return m_returnStatus;
+}
+
+void WrtInstaller::OnStop()
+{
+    _D("Stopping Dummy Client");
+}
+
+void WrtInstaller::OnCreate()
+{
+    _D("Creating DummyClient");
+
+    //pm lock
+    power_lock_state(POWER_STATE_SCREEN_OFF, 60*1000);
+
+    showArguments();
+
+    AddStep(&WrtInstaller::initStep);
+
+    std::string arg = m_argv[0];
+
+    using namespace PackageManager;
+
+    auto pkgmgrSignal = std::shared_ptr<PackageManager::PkgmgrSignal>(new PackageManager::PkgmgrSignal());
+
+    pkgmgrSignalInterface =
+        std::static_pointer_cast<PackageManager::IPkgmgrSignal>(
+            std::shared_ptr<PackageManager::PkgmgrSignalDummy>(
+                    new PackageManager::PkgmgrSignalDummy()));
+
+    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
+            return showHelpAndQuit();
+        } else if (arg == "-p" || arg == "--install-plugins") {
+            if (m_argc != 2) {
+                return showHelpAndQuit();
+            }
+
+            if (!m_startupPluginInstallation) {
+                AddStep(&WrtInstaller::installPluginsStep);
+            } else {
+                _D("Plugin installation alredy started");
+            }
+        } else if (arg == "-i" || arg == "--install") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+
+            struct stat info;
+            if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) {
+                _D("Installing package directly from directory");
+                m_installMode.extension = InstallMode::ExtensionType::DIR;
+            } else {
+                _D("Installing from regular location");
+                m_installMode.extension = InstallMode::ExtensionType::WGT;
+            }
+            m_packagePath = m_argv[2];
+            m_sendPkgSig = true;
+            pkgmgrSignal->initialize(m_argc, m_argv);
+            pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-ip" || arg == "--install-preload") {
+            _D("Install preload web app");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_packagePath = m_argv[2];
+            m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
+            m_installMode.rootPath = InstallMode::RootPath::RO;
+            m_installMode.removable = false;
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-ipw" || arg == "--install-preload-writable") {
+            _D("Install preload web application to writable storage");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_packagePath = m_argv[2];
+            m_installMode.installTime = InstallMode::InstallTime::PRELOAD;
+            m_installMode.rootPath = InstallMode::RootPath::RW;
+            m_installMode.removable = true;
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-c" || arg == "--csc-update") {
+            // "path=/opt/system/csc/Ozq2iEG15R-2.0.0-arm.wgt:op=install:removable=true"
+            _D("Install & uninstall by csc configuration");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_installMode.installTime = InstallMode::InstallTime::CSC;
+            std::string configuration = m_argv[2];
+
+            CommandParser::CscOption option;
+            if (!CommandParser::CscCommandParser(configuration, option)) {
+                return showHelpAndQuit();
+            }
+
+            if (0 == option.operation.compare(Command::VALUE_INSTALL)) {
+                m_installMode.extension = InstallMode::ExtensionType::WGT;
+                m_packagePath = option.path;
+                m_installMode.removable = option.removable;
+                m_installMode.cscPath = m_argv[2];
+                _D("operation = %s", option.operation.c_str());
+                _D("path      = %s", m_packagePath.c_str());
+                _D("removable = %d", m_installMode.removable);
+                _D("csc Path  = %s", m_installMode.cscPath.c_str());
+                AddStep(&WrtInstaller::installStep);
+            } else if (0 == option.operation.compare(Command::VALUE_UNINSTALL)){
+                m_packagePath = option.path;
+                _D("operation = %s", option.operation.c_str());
+                _D("path      = %s", m_packagePath.c_str());
+                AddStep(&WrtInstaller::unistallWgtFileStep);
+            } else {
+                _E("Unknown operation : %s", option.operation.c_str());
+                return showHelpAndQuit();
+            }
+        } else if (arg == "-un" || arg == "--uninstall-name") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_name = m_argv[2];
+            m_sendPkgSig = true;
+            m_argv[1] = (char*)"-d";
+            pkgmgrSignal->initialize(m_argc, m_argv);
+            pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
+            AddStep(&WrtInstaller::uninstallPkgNameStep);
+        } else if (arg == "-up" || arg == "--uninstall-packagepath") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            m_packagePath = m_argv[2];
+            AddStep(&WrtInstaller::unistallWgtFileStep);
+        } else if (arg == "-r" || arg == "--reinstall") {
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            _D("Installing package directly from directory");
+            m_installMode.command = InstallMode::Command::REINSTALL;
+            m_installMode.extension = InstallMode::ExtensionType::DIR;
+            m_packagePath = m_argv[2];
+            m_sendPkgSig = true;
+            pkgmgrSignal->initialize(m_argc, m_argv);
+            pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
+            AddStep(&WrtInstaller::installStep);
+        } else if (arg == "-f" || arg == "--fota") {
+            // "path=8HPzsUYyNZ:op=install"
+            _D("Install & uninstall by fota");
+            if (m_argc != 3) {
+                return showHelpAndQuit();
+            }
+            std::string configuration = m_argv[2];
+            CommandParser::FotaOption option;
+            if (!CommandParser::FotaCommandParser(configuration, option)) {
+                return showHelpAndQuit();
+            }
+
+            if ((0 == option.operation.compare(Command::VALUE_INSTALL)) ||
+                    (0 == option.operation.compare(Command::VALUE_UPGRADE)) ||
+                    (0 == option.operation.compare(Command::VALUE_UPDATE))) {
+                _D("FOTA ... Installation");
+                m_name = option.pkgId;
+                m_packagePath +=
+                    std::string(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath())
+                    + "/" + option.pkgId;
+                _D("package id   = %s", m_name.c_str());
+                _D("operation    = %s", option.operation.c_str());
+                _D("package path = %s", m_packagePath.c_str());
+
+                m_installMode.installTime = InstallMode::InstallTime::FOTA;
+                m_installMode.rootPath = InstallMode::RootPath::RO;
+                m_installMode.extension = InstallMode::ExtensionType::DIR;
+                AddStep(&WrtInstaller::installStep);
+            } else if (0 == option.operation.compare(Command::VALUE_UNINSTALL)){
+                _D("FOTA ... Uninstallation");
+                m_name = option.pkgId;
+                _D("package id   = %s", m_name.c_str());
+                AddStep(&WrtInstaller::uninstallPkgNameStep);
+            } else {
+                _E("Unknown operation : %s", option.operation.c_str());
+                return showHelpAndQuit();
+            }
+        } else if (arg == "-b" || arg == "--recovery") {
+            getRecoveryPackageId(m_name);
+            _D("m_name : %s", m_name.c_str());
+
+            if (!m_name.empty()) {
+                pkgmgrinfo_pkginfo_h handle = NULL;
+                if (0 == pkgmgrinfo_pkginfo_get_pkginfo(m_name.c_str(), &handle)) {
+                    m_installMode.command = InstallMode::Command::RECOVERY;
+                    m_installMode.extension = InstallMode::ExtensionType::DIR;
+                    AddStep(&WrtInstaller::installStep);
+                } else {
+                    _D("package id   = %s", m_name.c_str());
+                    AddStep(&WrtInstaller::uninstallPkgNameStep);
+                }
+            }
+        } else {
+            return showHelpAndQuit();
+        }
+    } else if (arg.find("backend") != std::string::npos) {
+        m_sendPkgSig = true;
+        pkgmgrSignal->initialize(m_argc, m_argv);
+        PkgmgrSignal::RequestType reqType = pkgmgrSignal->getRequestedType();
+        pkgmgrSignalInterface = std::static_pointer_cast<PackageManager::IPkgmgrSignal>(pkgmgrSignal);
+
+        switch (reqType) {
+        case PackageManager::PkgmgrSignal::RequestType::INSTALL:
+            m_packagePath = m_argv[4];
+            if (6 < m_argc) {
+                m_name = std::string(m_argv[6]);
+            }
+
+            struct stat info;
+            if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) {
+                _D("Installing package directly from directory");
+                m_installMode.extension = InstallMode::ExtensionType::DIR;
+            } else {
+                _D("Installing from regular location");
+                m_installMode.extension = InstallMode::ExtensionType::WGT;
+            }
+            AddStep(&WrtInstaller::installStep);
+            break;
+        case PackageManager::PkgmgrSignal::RequestType::UNINSTALL:
+        {
+            m_name = m_argv[4];
+            pkgmgrinfo_pkginfo_h handle = NULL;
+            bool preload = false;
+            bool system = false;
+            bool removable = true;
+            bool update = false;
+            char *cscPath = NULL;
+
+            if (0 == pkgmgrinfo_pkginfo_get_pkginfo(m_name.c_str(), &handle)) {
+                if (0 > pkgmgrinfo_pkginfo_is_preload(handle, &preload)) {
+                    _E("Can't get package information : %s", m_name.c_str());
+                }
+                if (0 > pkgmgrinfo_pkginfo_is_system(handle, &system)) {
+                    _E("Can't get package information : %s", m_name.c_str());
+                }
+                if (0 > pkgmgrinfo_pkginfo_is_removable(handle, &removable)) {
+                    _E("Can't get package information : %s", m_name.c_str());
+                }
+                if (0 > pkgmgrinfo_pkginfo_is_update(handle, &update)) {
+                    _E("Can't get package information about update : %s", m_name.c_str());
+                }
+                if (0 > pkgmgrinfo_pkginfo_get_csc_path(handle, &cscPath)) {
+                    _E("Can't get package information about update : %s", m_name.c_str());
+                }
+            }
+
+            _D("preload app : %d", preload);
+            _D("system app : %d", system);
+            _D("removable app : %d", removable);
+            _D("update : %d", update);
+            _D("csc path : %s", cscPath);
+
+            if (preload && update) {
+                if (system) {
+                    AddStep(&WrtInstaller::removeUpdateStep);
+                } else if (setInitialCSC(cscPath)) {
+                    AddStep(&WrtInstaller::uninstallPkgNameStep);
+                    AddStep(&WrtInstaller::installStep);
+                } else if (removable) {
+                    AddStep(&WrtInstaller::uninstallPkgNameStep);
+                }
+            } else {
+                AddStep(&WrtInstaller::uninstallPkgNameStep);
+            }
+            pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+            break;
+        }
+        case PackageManager::PkgmgrSignal::RequestType::REINSTALL:
+            m_packagePath = m_argv[4];
+            m_installMode.command = InstallMode::Command::REINSTALL;
+            m_installMode.extension = InstallMode::ExtensionType::DIR;
+            AddStep(&WrtInstaller::installStep);
+            break;
+        default:
+            _D("Not available type");
+            break;
+        }
+    }
+
+    AddStep(&WrtInstaller::shutdownStep);
+    DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
+        PostEvent(
+        WRTInstallerNS::NextStepEvent());
+}
+
+void WrtInstaller::OnReset(bundle* /*b*/)
+{
+    _D("OnReset");
+}
+
+void WrtInstaller::OnTerminate()
+{
+    _D("Wrt Shutdown now");
+
+    //pm unlock
+    power_unlock_state(POWER_STATE_SCREEN_OFF);
+
+    PluginUtils::unlockPluginInstallation(
+        m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
+    if (m_initialized) {
+        try {
+            _D("DEINITIALIZING WRT INSTALLER...");
+            // Installer termination
+            CONTROLLER_POST_SYNC_EVENT(
+                Logic::InstallerController,
+                InstallerControllerEvents::
+                    TerminateEvent());
+            InstallerMainThreadSingleton::Instance().DetachDatabases();
+            I18n::DB::Interface::detachDatabase();
+
+            // This must be done after DetachDatabase
+            ValidationCore::VCoreDeinit();
+
+            // Global deinit check
+            _D("Cleanup libxml2 global values.");
+            xmlCleanupParser();
+        } catch (const DPL::Exception& ex) {
+            _E("Internal Error during Shutdown:");
+            DPL::Exception::DisplayKnownException(ex);
+        }
+    }
+}
+
+void WrtInstaller::showHelpAndQuit()
+{
+    printf("Usage: wrt-installer [OPTION]... [WIDGET: ID/NAME/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 or update widget package for given path\n"
+           "  -c,    --csc-update                           "
+           "install or uninstall by CSC configuration \n"
+           "  -un,   --uninstall-name                       "
+           "uninstall widget for given package name\n"
+           "  -up,   --uninstall-packagepath                "
+           "uninstall widget for given package file path\n"
+           "  -r,    --reinstall                            "
+           "reinstall mode for sdk (this is NOT normal reinstallation/update)\n"
+           "\n");
+
+    Quit();
+}
+
+void WrtInstaller::showArguments()
+{
+    fprintf(stderr,
+            "===========================================================\n");
+    fprintf(stderr, "# wrt-installer #\n");
+    fprintf(stderr, "# argc [%d]\n", m_argc);
+    for (int i = 0; i < m_argc; i++) {
+        fprintf(stderr, "# argv[%d] = [%s]\n", i, m_argv[i]);
+    }
+    fprintf(stderr,
+            "===========================================================\n");
+    // for dlog
+    _D("===========================================================");
+    _D("# wrt-installer #");
+    _D("# argc %d", m_argc);
+    for (int i = 0; i < m_argc; i++) {
+        _D("# argv[%d] = %s", i, m_argv[i]);
+    }
+    _D("===========================================================");
+
+}
+
+void WrtInstaller::OnEventReceived(const WRTInstallerNS::QuitEvent& /*event*/)
+{
+    _D("Quiting");
+
+    if (m_initialized) {
+        _D("Wrt Shutdown now");
+        SwitchToStep(&WrtInstaller::shutdownStep);
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>::
+            PostEvent(
+            WRTInstallerNS::NextStepEvent());
+    } else {
+        _D("Quiting application");
+        return Quit();
+    }
+}
+
+void WrtInstaller::OnEventReceived(
+    const WRTInstallerNS::NextStepEvent& /*event*/)
+{
+    _D("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();
+
+        _D("INSTALL PLUGIN: %s", privateData->pluginPath.c_str());
+        //Private data for status callback
+        //Resource is free in pluginInstallFinishedCallback
+        InstallerCallbacksTranslate::PluginStatusCallbackStruct*
+        callbackStruct =
+            new InstallerCallbacksTranslate::PluginStatusCallbackStruct(
+                privateData, &staticWrtPluginInstallationCallback, &staticWrtPluginInstallProgressCb);
+
+        CONTROLLER_POST_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::InstallPluginEvent(
+                privateData->pluginPath,
+                PluginInstallerStruct(
+                    InstallerCallbacksTranslate::
+                        pluginInstallFinishedCallback,
+                    InstallerCallbacksTranslate::
+                        installProgressCallback, callbackStruct)));
+    } else {
+        delete privateData;
+    }
+}
+
+void WrtInstaller::initStep()
+{
+    try {
+        _D("INITIALIZING WRT INSTALLER...");
+
+        // Touch InstallerController Singleton
+        InstallerMainThreadSingleton::Instance().TouchArchitecture();
+
+        // Check paths
+        if (!checkPaths()) {
+            makeStatusOfWrtInit(WRT_INSTALLER_ERROR_FATAL_ERROR);
+            return;
+        }
+
+        // Initialize ValidationCore - this must be done before AttachDatabases
+        ValidationCore::VCoreInit(
+            std::string(GlobalConfig::GetFingerprintListFile()),
+            std::string(GlobalConfig::GetFingerprintListSchema()),
+            std::string(GlobalConfig::GetVCoreDatabaseFilePath()));
+
+        InstallerMainThreadSingleton::Instance().AttachDatabases();
+
+        _D("Prepare libxml2 to work in multithreaded program.");
+        xmlInitParser();
+
+        // Initialize Language Subtag registry
+        LanguageSubtagRstTreeSingleton::Instance().Initialize();
+
+        // Installer init
+        CONTROLLER_POST_SYNC_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::
+                InitializeEvent());
+
+        makeStatusOfWrtInit(WRT_SUCCESS);
+    } catch (const DPL::Exception& ex) {
+        _E("Internal Error during Init:");
+        DPL::Exception::DisplayKnownException(ex);
+        makeStatusOfWrtInit(WRT_INSTALLER_ERROR_FATAL_ERROR);
+    }
+}
+
+void WrtInstaller::installStep()
+{
+    std::unique_ptr<char, free_deleter> packagePath(canonicalize_file_name(
+                                                        m_packagePath.c_str()));
+
+    if (InstallMode::InstallTime::PRELOAD == m_installMode.installTime) {
+        DPL::Log::OldStyleLogProvider *oldStyleProvider =
+            new DPL::Log::OldStyleLogProvider(false, false, false, true,
+                    false, true);
+        DPL::Log::LogSystemSingleton::Instance().AddProvider(oldStyleProvider);
+    }
+
+    std::string path = packagePath ? packagePath.get() : m_packagePath.c_str();
+    _D("INSTALL WIDGET: %s", path.c_str());
+    // Post installation event
+    CONTROLLER_POST_EVENT(
+        Logic::InstallerController,
+        InstallerControllerEvents::InstallWidgetEvent(
+            path, m_name.c_str(),
+            Jobs::WidgetInstall::WidgetInstallationStruct(
+                InstallerCallbacksTranslate::installFinishedCallback,
+                InstallerCallbacksTranslate::installProgressCallback,
+                new InstallerCallbacksTranslate::StatusCallbackStruct(
+                    this, &staticWrtStatusCallback, (m_sendPkgSig)
+                            ? &staticWrtInstallProgressCallback : NULL),
+                m_installMode, pkgmgrSignalInterface)));
+}
+
+void WrtInstaller::installPluginsStep()
+{
+    _D("Installing plugins ...");
+    fprintf(stderr, "Installing plugins ...\n");
+
+    if (m_startupPluginInstallation) {
+        _D("Plugin installation started because new plugin package found");
+    } else if (!PluginUtils::lockPluginInstallation(
+        m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
+    {
+        _E("Failed to open plugin installation lock file"
+                 " Plugins are currently installed by other process");
+        staticWrtPluginInstallationCallback(WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
+                                            this);
+        return;
+    }
+
+    std::string PLUGIN_PATH = std::string(GlobalConfig::GetDevicePluginPath());
+
+    DIR *dir;
+    dir = opendir(PLUGIN_PATH.c_str());
+
+    if (!dir) {
+        return;
+    }
+
+    _D("Plugin DIRECTORY IS %s", PLUGIN_PATH.c_str());
+
+    std::list<std::string> pluginsPaths;
+    struct dirent libdir;
+    struct dirent *result;
+    int return_code;
+    errno = 0;
+    for (return_code = readdir_r(dir, &libdir, &result);
+            result != NULL && return_code == 0;
+            return_code = readdir_r(dir, &libdir, &result))
+    {
+        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) {
+            _E("Failed to open file %s", path.c_str());
+            continue;
+        }
+
+        if (!S_ISDIR(tmp.st_mode)) {
+            _E("Not a directory %s", path.c_str());
+            continue;
+        }
+
+        pluginsPaths.push_back(path);
+    }
+
+    if (return_code != 0 || errno != 0) {
+        _E("readdir_r() failed with %s", DPL::GetErrnoString().c_str());
+    }
+
+    //set nb of plugins to install
+    //this value indicate how many callbacks are expected
+    m_numPluginsToInstall = pluginsPaths.size();
+    _D("Plugins to install: %d", m_numPluginsToInstall);
+    m_pluginsPaths = pluginsPaths;
+
+    m_totalPlugins = m_numPluginsToInstall;
+    DPL::Event::ControllerEventHandler<WRTInstallerNS::InstallPluginEvent>
+        ::PostEvent(WRTInstallerNS::InstallPluginEvent());
+
+    if (-1 == closedir(dir)) {
+        _E("Failed to close dir: %s with error: %s", PLUGIN_PATH.c_str(), DPL::GetErrnoString().c_str());
+    }
+}
+
+void WrtInstaller::uninstallPkgNameStep()
+{
+    _D("Package name : %s", m_name.c_str());
+
+    _D("UNINSTALL WIDGET: %s", m_name.c_str());
+    // Post uninstallation event
+    CONTROLLER_POST_EVENT(
+        Logic::InstallerController,
+        InstallerControllerEvents::UninstallWidgetEvent(
+            m_name,
+            WidgetUninstallationStruct(
+                InstallerCallbacksTranslate::uninstallFinishedCallback,
+                InstallerCallbacksTranslate::installProgressCallback,
+                new InstallerCallbacksTranslate::StatusCallbackStruct(
+                    this, &staticWrtStatusCallback,
+                    (m_sendPkgSig) ? &staticWrtUninstallProgressCallback : NULL),
+                pkgmgrSignalInterface)
+            )
+        );
+}
+
+void WrtInstaller::removeUpdateStep()
+{
+    _D("This web app need to initialize preload app");
+    _D("Package name : %s", m_name.c_str());
+
+    _D("UNINSTALL WIDGET: %s", m_name.c_str());
+    // Post uninstallation event
+    CONTROLLER_POST_EVENT(
+        Logic::InstallerController,
+        InstallerControllerEvents::UninstallWidgetEvent(
+            m_name,
+            WidgetUninstallationStruct(
+                InstallerCallbacksTranslate::uninstallFinishedCallback,
+                InstallerCallbacksTranslate::installProgressCallback,
+                new InstallerCallbacksTranslate::StatusCallbackStruct(
+                    this, &staticWrtInitializeToPreloadCallback, (m_sendPkgSig)
+                            ? &staticWrtUninstallProgressCallback : NULL),
+                pkgmgrSignalInterface
+                )
+            )
+        );
+}
+
+bool WrtInstaller::setInitialCSC(std::string cscPath)
+{
+    _D("This web app need to initialize initial csc app");
+    _D("UNINSTALL WIDGET: %s", m_name.c_str());
+    _D("csc path: %s", cscPath.c_str());
+
+    m_installMode.installTime = InstallMode::InstallTime::CSC;
+    std::string configuration = cscPath;
+
+    CommandParser::CscOption option;
+    if (!CommandParser::CscCommandParser(configuration, option)) {
+        _E("Failure command parser");
+        return false;
+    }
+
+    if (0 == option.operation.compare(Command::VALUE_INSTALL)) {
+        m_installMode.extension = InstallMode::ExtensionType::WGT;
+        m_packagePath = option.path;
+        m_installMode.removable = option.removable;
+        m_installMode.cscPath = cscPath;
+        _D("operation = %s", option.operation.c_str());
+        _D("path      = %s", m_packagePath.c_str());
+        _D("removable      = %d", m_installMode.removable);
+        _D("csc Path = %s", m_installMode.cscPath.c_str());
+    } else {
+        _E("Unknown operation : %s", option.operation.c_str());
+        return false;
+    }
+    return true;
+}
+
+void WrtInstaller::unistallWgtFileStep()
+{
+    _D("Uninstalling widget ...");
+
+    Try {
+        // Parse config
+        ParserRunner parser;
+        ConfigParserData configInfo;
+
+        // Open zip file
+        std::unique_ptr<DPL::ZipInput> zipFile(
+            new DPL::ZipInput(m_packagePath));
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        Try {
+            // Open config.xml file
+            configFile.reset(zipFile->OpenFile(CONFIG_XML));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            // Open config.xml file for hybrid
+            configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML));
+        }
+
+        // Extract config
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        parser.Parse(&buffer,
+                     ElementParserPtr(
+                         new RootParser<WidgetParser>(configInfo,
+                                                      DPL::FromUTF32String(
+                                                          L"widget"))));
+
+        DPL::OptionalString pkgId = configInfo.tizenPkgId;
+        if (!!pkgId) {
+            _D("Pkgid from packagePath : %ls", (*pkgId).c_str());
+            _D("UNINSTALL WIDGET: %s", DPL::ToUTF8String(*pkgId).c_str());
+            // Post uninstallation event
+            CONTROLLER_POST_EVENT(
+                Logic::InstallerController,
+                InstallerControllerEvents::UninstallWidgetEvent(
+                    DPL::ToUTF8String(*pkgId),
+                    WidgetUninstallationStruct(
+                        InstallerCallbacksTranslate::uninstallFinishedCallback,
+                        InstallerCallbacksTranslate::installProgressCallback,
+                        new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            this, &staticWrtStatusCallback, !m_sendPkgSig
+                            ? &staticWrtUninstallProgressCallback : NULL),
+                            pkgmgrSignalInterface)
+                    )
+                );
+
+        } else {
+            _E("Fail to uninstalling widget... ");
+            m_returnStatus = -1;
+            DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+                PostEvent(
+                WRTInstallerNS::QuitEvent());
+        }
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        _E("Failed to open widget package");
+        printf("failed: widget package does not exist\n");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        printf("failed: widget config file does not exist\n");
+        _E("Failed to open config.xml file");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        printf("failed: can not parse config file\n");
+        _E("Failed to parse config.xml file");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+    Catch(DPL::Exception)
+    {
+        printf("Unknown DPL exception\n");
+        _E("Unknown DPL exception");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+}
+
+void WrtInstaller::shutdownStep()
+{
+    _D("Closing Wrt connection ...");
+    if (m_initialized) {
+        try {
+            _D("DEINITIALIZING WRT INSTALLER...");
+            // Installer termination
+            CONTROLLER_POST_SYNC_EVENT(
+                Logic::InstallerController,
+                InstallerControllerEvents::
+                    TerminateEvent());
+
+            InstallerMainThreadSingleton::Instance().DetachDatabases();
+
+            // This must be done after DetachDatabase
+            ValidationCore::VCoreDeinit();
+
+            // Global deinit check
+            _D("Cleanup libxml2 global values.");
+            xmlCleanupParser();
+        } catch (const DPL::Exception& ex) {
+            _E("Internal Error during Shutdown:");
+            DPL::Exception::DisplayKnownException(ex);
+        }
+        m_initialized = false;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+}
+
+void WrtInstaller::makeStatusOfWrtInit(WrtErrStatus status)
+{
+    if (status == WRT_SUCCESS) {
+        _D("Init succesfull");
+        m_initialized = true;
+        m_returnStatus = 0;
+
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    } else {
+        _E("Init unsuccesfull");
+        m_returnStatus = -1;
+        DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>::
+            PostEvent(
+            WRTInstallerNS::QuitEvent());
+    }
+}
+
+void WrtInstaller::staticWrtInitializeToPreloadCallback(std::string tizenId, WrtErrStatus
+        status, void* userdata)
+{
+    WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    Assert(This);
+
+    std::string printMsg = "uninstallation";
+
+    if (WRT_SUCCESS != status) {
+        // Failure
+        _E("Step failed");
+        This->m_returnStatus = 1;
+
+        This->showErrorMsg(status, tizenId, printMsg);
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
+            ::PostEvent(WRTInstallerNS::QuitEvent());
+    } else {
+        InstallMode mode;
+        mode.extension = InstallMode::ExtensionType::DIR;
+        mode.installTime = InstallMode::InstallTime::PRELOAD;
+        mode.rootPath = InstallMode::RootPath::RO;
+        std::string packagePath =
+            std::string(WrtDB::GlobalConfig::GetUserPreloadedWidgetPath())
+                + "/" + This->m_name;
+
+        if (InstallMode::InstallTime::PRELOAD == This->m_installMode.installTime) {
+            DPL::Log::OldStyleLogProvider *oldStyleProvider =
+                new DPL::Log::OldStyleLogProvider(false, false, false, true,
+                        false, true);
+            DPL::Log::LogSystemSingleton::Instance().AddProvider(oldStyleProvider);
+        }
+
+        _D("INSTALL WIDGET: %s", packagePath.c_str());
+        // Post installation event
+        CONTROLLER_POST_EVENT(
+            Logic::InstallerController,
+            InstallerControllerEvents::InstallWidgetEvent(
+                packagePath, tizenId.c_str(), Jobs::WidgetInstall::WidgetInstallationStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                        This, &staticWrtInitPreloadStatusCallback, NULL),
+                    mode,
+                    This->pkgmgrSignalInterface)));
+    }
+}
+
+void WrtInstaller::staticWrtInitPreloadStatusCallback(std::string tizenId,
+                                           WrtErrStatus status,
+                                           void* userdata)
+{
+    WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    Assert(This);
+
+    std::string printMsg = "initialization";
+
+    if (WRT_SUCCESS != status) {
+        // Failure
+        _E("Step failed");
+        This->m_returnStatus = status;
+
+        This->showErrorMsg(status, tizenId, printMsg);
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
+            ::PostEvent(WRTInstallerNS::QuitEvent());
+    } else {
+        fprintf(stderr,
+                "## wrt-installer : %s %s was successful.\n",
+                tizenId.c_str(),
+                printMsg.c_str());
+        _D("Status succesfull");
+        This->m_returnStatus = 0;
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
+                                                     NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    }
+}
+
+void WrtInstaller::staticWrtStatusCallback(std::string tizenId,
+                                           WrtErrStatus status,
+                                           void* userdata)
+{
+    WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    Assert(This);
+
+    Step current = This->GetCurrentStep();
+    std::string printMsg;
+
+    if (current == &WrtInstaller::installStep) {
+        printMsg = "installation";
+    } else if (current == &WrtInstaller::uninstallPkgNameStep ||
+               current == &WrtInstaller::unistallWgtFileStep)
+    {
+        printMsg = "uninstallation";
+    }
+
+    if (WRT_SUCCESS != status) {
+        // Failure
+        _E("Step failed");
+        This->m_returnStatus = status;
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::QuitEvent>
+            ::PostEvent(WRTInstallerNS::QuitEvent());
+
+        This->showErrorMsg(status, tizenId, printMsg);
+    } else {
+        fprintf(stderr,
+                "## wrt-installer : %s %s was successful.\n",
+                tizenId.c_str(),
+                printMsg.c_str());
+        _D("Status succesfull");
+        This->m_returnStatus = 0;
+
+        if (This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD &&
+                !This->m_packagePath.empty())
+        {
+            _D("This widget is preloaded so it will be removed : %s", This->m_packagePath.c_str());
+            if (!WrtUtilRemove(This->m_packagePath)) {
+                _E("Failed to remove %s", This->m_packagePath.c_str());
+            }
+        }
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
+                                                     NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    }
+}
+
+void WrtInstaller::showErrorMsg(WrtErrStatus status, std::string tizenId,
+        std::string printMsg)
+{
+    switch (status) {
+        case WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - widget package does not exist\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PACKAGE_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - invalid widget package\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - given"
+                    " version is lower than existing version\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - manifest"
+                    " file doesn't find in package.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MANIFEST_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid manifestx.xml\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_CONFIG_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "config.xml does not exist\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CONFIG_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid config.xml\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "signature doesn't exist in package.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_SIGNATURE_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid signature.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "signature verification failed.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "root certificate could not find.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CERTIFICATION_INVAID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid certification.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "certificate chain verification failed.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "certificate expired.\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_INVALID_PRIVILEGE:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid privilege\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "privilege level violation\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "menu icon could not find\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_FATAL_ERROR:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "fatal error\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_OUT_OF_STORAGE:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "out of storage\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_OUT_OF_MEMORY:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "out of memory\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ARGUMENT_INVALID:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "invalid argument\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "package already installed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ACE_CHECK_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "ace check failure\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "to create manifest failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_ENCRYPTION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "encryption of resource failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "installation of osp service failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        case WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED:
+            fprintf(stderr, "## wrt-installer : %s %s has failed - "
+                    "widget uninstallation failed\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+
+        case WRT_INSTALLER_ERROR_UNKNOWN:
+            fprintf(stderr,"## wrt-installer : %s %s has failed - unknown error\n",
+                    tizenId.c_str(), printMsg.c_str());
+            break;
+
+        default:
+            break;
+    }
+
+}
+
+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--;
+    _D("Plugins to install: %d", This->m_numPluginsToInstall);
+
+    if (This->m_numPluginsToInstall < 1) {
+        _D("All plugins installation completed");
+        fprintf(stderr, "All plugins installation completed.\n");
+
+        //remove installation request
+        if (!PluginUtils::removeInstallationRequiredFlag()) {
+            _D("Failed to remove file initializing plugin installation");
+        }
+
+        //remove lock file
+        if (!PluginUtils::unlockPluginInstallation(
+            This->m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
+        {
+            _D("Failed to remove installation lock");
+        }
+
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::NextStepEvent>
+            ::PostEvent(WRTInstallerNS::NextStepEvent());
+    } else {
+        This->DPL::Event::ControllerEventHandler<WRTInstallerNS::
+                                                     InstallPluginEvent>::
+            PostEvent(
+            WRTInstallerNS::InstallPluginEvent());
+    }
+
+    if (WRT_SUCCESS == status) {
+        This->m_returnStatus = 0;
+        fprintf(stderr,
+                "## wrt-installer : plugin installation successfull [%s]\n",
+                path.c_str());
+        _D("One plugin Installation succesfull: %s", path.c_str());
+        return;
+    }
+
+    // Failure
+    _W("One of the plugins installation failed!: %s", path.c_str());
+
+    switch (status) {
+    case WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED:
+        _E("failed: plugin installation failed\n");
+        break;
+
+    case WRT_INSTALLER_ERROR_UNKNOWN:
+        _E("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);
+
+    _D("Plugin Installation: %s progress: %2.0f description: %s", path.c_str(), percent, description);
+}
+
+void WrtInstaller::staticWrtInstallProgressCallback(float percent,
+                                                    const char* description,
+                                                    void* /*userdata*/)
+{
+    //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    _D(" progress: %2.0f description: %s", percent, description);
+}
+void WrtInstaller::staticWrtUninstallProgressCallback(float percent,
+                                                      const char* description,
+                                                      void* /*userdata*/)
+{
+    //WrtInstaller *This = static_cast<WrtInstaller*>(userdata);
+    _D(" progress: %2.0f description: %s", percent, description);
+}
+
+void WrtInstaller::installNewPlugins()
+{
+    _D("Install new plugins");
+
+    if (!PluginUtils::lockPluginInstallation(
+        m_installMode.installTime == InstallMode::InstallTime::PRELOAD))
+    {
+        _D("Lock NOT created");
+        return;
+    }
+
+    if (!PluginUtils::checkPluginInstallationRequired()) {
+        _D("Plugin installation not required");
+        PluginUtils::unlockPluginInstallation(
+            m_installMode.installTime == InstallMode::InstallTime::PRELOAD);
+        return;
+    }
+
+    m_startupPluginInstallation = true;
+    AddStep(&WrtInstaller::installPluginsStep);
+}
+
+void WrtInstaller::getRecoveryPackageId(std::string &pkgId)
+{
+    _D("getRecoveryPackageId");
+    std::string folderPath =
+        std::string(WrtDB::GlobalConfig::GetTempInstallInfoPath()) + "/";
+
+    DIR* dir = opendir(folderPath.c_str());
+    if (NULL == dir) {
+        return;
+    }
+
+    struct dirent dEntry;
+    struct dirent *dEntryResult;
+    int return_code;
+
+    do {
+        struct stat statInfo;
+        return_code = readdir_r(dir, &dEntry, &dEntryResult);
+        if (dEntryResult != NULL && return_code == 0) {
+            std::string fileName = dEntry.d_name;
+            std::string fullName = folderPath + "/" + fileName;
+
+            if (stat(fullName.c_str(), &statInfo) != 0) {
+                closedir(dir);
+                return;
+            }
+
+            if (S_ISDIR(statInfo.st_mode)) {
+                if (("." == fileName) || (".." == fileName)) {
+                    continue;
+                }
+            } else {
+                pkgId = fileName;
+                if (0 != unlink(fullName.c_str())) {
+                    _E("Fail to delete : %s", fullName.c_str());
+                }
+            }
+        }
+    } while (dEntryResult != NULL && return_code == 0);
+    closedir(dir);
+}
+
+#if 0
+void shell(const char* cmd) {
+    char buf[256];
+    FILE *fp;
+
+    _E("### %s ###", cmd);
+    fp = popen(cmd, "r");
+    if (fp == NULL) {
+        _E("error: fp is NULL");
+    } else {
+        while(fgets(buf, 256, fp) != NULL) {
+            _E("%s", buf);
+        }
+        pclose(fp);
+    }
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+    UNHANDLED_EXCEPTION_HANDLER_BEGIN
+    {
+        DPL::Log::LogSystemSingleton::Instance().SetTag("WRT_INSTALLER");
+
+        // 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);
+
+        // Check and re-set the file open limitation
+        struct rlimit rlim;
+        if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) {
+            _D("RLIMIT_NOFILE sft(%d)", rlim.rlim_cur);
+            _D("RLIMIT_NOFILE hrd(%d)", rlim.rlim_max);
+
+            if (rlim.rlim_cur < NOFILE_CNT_FOR_INSTALLER) {
+                rlim.rlim_cur = NOFILE_CNT_FOR_INSTALLER;
+                rlim.rlim_max = NOFILE_CNT_FOR_INSTALLER;
+                if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
+                    _E("setrlimit is fail!!");
+                }
+            }
+        } else {
+            _E("getrlimit is fail!!");
+        }
+
+        WrtInstaller app(argc, argv);
+        int ret = app.Exec();
+        // In FOTA environment, appcore will return -1 due to /tmp is read-only.
+        if (ret != 0) {
+            app.OnCreate();
+            elm_run();
+            app.OnTerminate();
+        }
+        _D("App returned: %d", ret);
+        ret = app.getReturnStatus();
+        _D("WrtInstaller returned: %d", ret);
+        return ret;
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+}
diff --git a/src_wearable/wrt-installer/wrt-installer.h b/src_wearable/wrt-installer/wrt-installer.h
new file mode 100755 (executable)
index 0000000..a60d36c
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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_INSTALLER_H
+#define WRT_INSTALLER_H
+
+#include <dpl/application.h>
+#include <dpl/generic_event.h>
+#include <dpl/event/controller.h>
+#include <dpl/task.h>
+#include <dpl/string.h>
+#include <string>
+#include <map>
+#include <boost/optional.hpp>
+#include <wrt_install_mode.h>
+#include <wrt_type.h>
+#include <pkgmgr_signal.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);
+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;
+
+    virtual void OnStop();
+    virtual void OnCreate();
+    virtual void OnReset(bundle *b);
+    virtual void OnTerminate();
+
+  private:
+    void         showHelpAndQuit();
+    void         showArguments();
+
+    // 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 installPluginsStep();
+    void uninstallPkgNameStep();
+    void unistallWgtFileStep();
+    void removeUpdateStep();
+    void shutdownStep();
+
+    // Static callbacks
+    static void staticWrtStatusCallback(std::string tizenId,
+                                        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 staticWrtInitializeToPreloadCallback(std::string tizenId,
+                                        WrtErrStatus status,
+                                        void* userdata);
+
+    static void staticWrtInitPreloadStatusCallback(std::string tizenId,
+                                        WrtErrStatus status,
+                                        void* userdata);
+
+    void installNewPlugins();
+    void showErrorMsg(WrtErrStatus status, std::string tizenId, std::string
+            printMsg);
+
+    void makeStatusOfWrtInit(WrtErrStatus status);
+    void getRecoveryPackageId(std::string &pkgId);
+    bool setInitialCSC(std::string cscPath);
+
+    // Private data
+    std::shared_ptr<PackageManager::IPkgmgrSignal> pkgmgrSignalInterface;
+    InstallMode m_installMode;
+    std::string m_packagePath;
+    std::string m_name;
+    bool m_initialized;
+    size_t m_numPluginsToInstall;
+    size_t m_totalPlugins;
+    int m_returnStatus;
+    bool m_sendPkgSig;
+    bool m_startupPluginInstallation;
+
+    typedef std::list<std::string> PluginPathList;
+    boost::optional<PluginPathList> m_pluginsPaths;
+};
+#endif // WRT_INSTALLER_H
diff --git a/src_wearable/wrt-installer/wrt_type.h b/src_wearable/wrt-installer/wrt_type.h
new file mode 100644 (file)
index 0000000..3a5ed67
--- /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        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>
+
+#define WRT_DEPRECATED __attribute__((deprecated))
+
+typedef enum
+{
+    /* Generic success */
+    WRT_SUCCESS = 0,                /*< Success*/
+
+    /* pkgmgr error */
+    WRT_INSTALLER_ERROR_PACKAGE_NOT_FOUND,      ///<
+    WRT_INSTALLER_ERROR_PACKAGE_INVALID,        ///< invalid widget package
+    WRT_INSTALLER_ERROR_PACKAGE_LOWER_VERSION,  ///< given version is lower than existing version
+    WRT_INSTALLER_ERROR_PACKAGE_EXCUTABLE_NOT_FOUND,
+
+    WRT_INSTALLER_ERROR_MANIFEST_NOT_FOUND = 11,///<
+    WRT_INSTALLER_ERROR_MANIFEST_INVALID,       ///<
+    WRT_INSTALLER_CONFIG_NOT_FOUND,             ///< couldn't find config.xml
+                                                ///< in package.
+    WRT_INSTALLER_ERROR_CONFIG_INVALID,         ///< invalid config.xml
+
+    WRT_INSTALLER_ERROR_SIGNATURE_NOT_FOUND = 21,    ///< signature file not exist.
+    WRT_INSTALLER_ERROR_SIGNATURE_INVALID,           ///< invalid signature file
+    WRT_INSTALLER_ERROR_SIGNATURE_VERIFICATION_FAILED,  ///< failure in verificate signature
+    WRT_INSTALLER_ERROR_ROOT_CERTIFICATE_NOT_FOUND = 31, ///< couldn't find root certificate.
+    WRT_INSTALLER_ERROR_CERTIFICATION_INVAID,       ///< invalid certification
+    WRT_INSTALLER_ERROR_CERTIFICATE_CHAIN_VERIFICATION_FAILED,    ///< failure in verificate certification chain.
+    WRT_INSTALLER_ERROR_CERTIFICATE_EXPIRED,        ///< expire cerification.
+
+    WRT_INSTALLER_ERROR_INVALID_PRIVILEGE = 41,     ///< invalid privilege.
+    WRT_INSTALLER_ERROR_PRIVILEGE_LEVEL_VIOLATION,
+
+    WRT_INSTALLER_ERROR_MENU_ICON_NOT_FOUND = 51,   ///<
+
+    WRT_INSTALLER_ERROR_FATAL_ERROR = 61,           ///< failure in db operation or file opertion..
+    WRT_INSTALLER_ERROR_OUT_OF_STORAGE,             ///< failure in shortage of memory
+    WRT_INSTALLER_ERROR_OUT_OF_MEMORY,              ///< failure in shortage of RAM
+    WRT_INSTALLER_ERROR_ARGUMENT_INVALID,
+
+    /* wrt-installer error */
+    /* 121-140 : reserved for Web installer */
+
+    /* installation */
+    WRT_INSTALLER_ERROR_PACKAGE_ALREADY_INSTALLED = 121,
+    WRT_INSTALLER_ERROR_ACE_CHECK_FAILED,
+    WRT_INSTALLER_ERROR_MANIFEST_CREATE_FAILED,     ///<
+    WRT_INSTALLER_ERROR_ENCRYPTION_FAILED,          ///< Failure in reousrce encrypttion
+    WRT_INSTALLER_ERROR_INSTALL_OSP_SERVCIE,        ///< Failure in installing osp service
+    WRT_INSTALLER_ERROR_PLUGIN_INSTALLATION_FAILED,
+    WRT_INSTALLER_ERROR_UNINSTALLATION_FAILED,
+
+    WRT_INSTALLER_ERROR_UNKNOWN = 140,              ///< do not use this error code.
+
+} WrtErrStatus;
+
+#endif /* WRT_TYPE_H_ */
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5951524
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright (c) 2013 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      Karol Pawlowski (k.pawlowski@samsung.com)
+#
+
+
+ADD_SUBDIRECTORY(general)
diff --git a/tests/general/AceRegistrationTests.cpp b/tests/general/AceRegistrationTests.cpp
new file mode 100644 (file)
index 0000000..969c194
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2013 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    AceRegistrationTests.cpp
+ * @author  Dominik Duda (d.duda@samsung.com)
+ * @version 1.0
+ * @brief   Tests functions from wrt-installer/src/jobs/widget_install/ace_registration.cpp
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <InstallerWrapper.h>
+#include <ace_registration.h>
+#include <ace_api_install.h>
+
+
+using namespace AceApi;
+using namespace WrtDB;
+using namespace InstallerWrapper;
+
+RUNNER_TEST_GROUP_INIT(AceRegistration)
+
+namespace{
+    const std::string wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+
+    std::string tizenId;
+    DbWidgetHandle wgtHandle;
+}
+
+/*
+Name: ace_registration_tests_00
+Description: Install a widget which is needed for further tests.
+Expected: The widget should be successfully installed.
+*/
+RUNNER_TEST(ace_registration_tests_00)
+{
+    RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed to install widget");
+
+    wgtHandle = WidgetDAOReadOnly::getHandle(DPL::FromUTF8String(tizenId));
+}
+
+/*
+Name: ace_registration_tests_01
+Description: Tests registration of the widget in ACE database.
+Expected: The widget should be successfully registered.
+*/
+RUNNER_TEST(ace_registration_tests_01)
+{
+    bool test1;
+    ace_return_t test2, test3, test4;
+    WidgetRegisterInfo regInfo;
+    WidgetCertificateDataList certificates;
+    WidgetCertificateData cert1, cert2, cert3;
+
+    regInfo.webAppType.appType = WrtDB::APP_TYPE_TIZENWEBAPP;
+    regInfo.configInfo.widget_id = DPL::FromUTF8String(tizenId);
+    regInfo.configInfo.version = DPL::FromUTF8String("1.0");
+    regInfo.configInfo.authorName = DPL::FromUTF8String("Author");
+
+    cert1.owner = WidgetCertificateData::Owner::AUTHOR;
+    cert1.type = WidgetCertificateData::Type::ROOT;
+    cert1.chainId = wgtHandle;
+    cert1.strMD5Fingerprint = "";
+    cert1.strSHA1Fingerprint = "";
+    cert1.strCommonName = DPL::FromUTF8String("");
+
+    cert2.owner = WidgetCertificateData::Owner::DISTRIBUTOR;
+    cert2.type = WidgetCertificateData::Type::ENDENTITY;
+    cert2.chainId = wgtHandle;
+    cert2.strMD5Fingerprint = "";
+    cert2.strSHA1Fingerprint = "";
+    cert2.strCommonName = DPL::FromUTF8String("");
+
+    cert3.owner = WidgetCertificateData::Owner::UNKNOWN;
+    cert3.type = static_cast<WrtDB::WidgetCertificateData::Type>(2);
+    cert3.chainId = wgtHandle;
+    cert3.strMD5Fingerprint = "";
+    cert3.strSHA1Fingerprint = "";
+    cert3.strCommonName = DPL::FromUTF8String("");
+
+    certificates.push_back(cert1);
+    certificates.push_back(cert2);
+    certificates.push_back(cert3);
+
+    test2 = ace_install_initialize();
+    wgtHandle = WidgetDAOReadOnly::getHandle(DPL::FromUTF8String(tizenId));
+
+    //Unregister widget in ACE db in order to test registerAceWidget function
+    test3 = ace_unregister_widget(
+            static_cast<ace_widget_handle_t>(wgtHandle));
+    test1 = registerAceWidget(wgtHandle, regInfo, certificates);
+    test4 = ace_install_shutdown();
+
+    RUNNER_ASSERT_MSG(test1, "Registering widget from the DB failed!");
+    RUNNER_ASSERT_MSG(test2 == ACE_OK, "Cannot initialize ACE database!");
+    RUNNER_ASSERT_MSG(test2 == ACE_OK, "Cannot unregister widget in ACE database!");
+    RUNNER_ASSERT_MSG(test2 == ACE_OK, "Shutting down ACE database failed!");
+}
+
+/*
+Name: ace_registration_tests_02
+Description: Tests registration of the widget which data already are in
+the database.
+Expected: The widget should be successfully registered.
+*/
+RUNNER_TEST(ace_registration_tests_02)
+{
+    bool test1;
+    ace_return_t test2, test3, test4;
+
+    test2 = ace_install_initialize();
+
+    //Unregister widget in ACE db in order to test registerAceWidgetFromDB
+    //function
+    test3 = ace_unregister_widget(
+            static_cast<ace_widget_handle_t>(wgtHandle));
+    test1 = registerAceWidgetFromDB(wgtHandle);
+    test4 = ace_install_shutdown();
+
+    RUNNER_ASSERT_MSG(test1, "Registering widget from the DB failed!");
+    RUNNER_ASSERT_MSG(test2 == ACE_OK, "Cannot initialize ACE database!");
+    RUNNER_ASSERT_MSG(test2 == ACE_OK, "Cannot unregister widget in ACE database!");
+    RUNNER_ASSERT_MSG(test2 == ACE_OK, "Shutting down ACE database failed!");
+}
+
+/*
+Name: ace_registration_tests_03
+Description: Uninstalls the widget previously installed for tests.
+Expected: The widget should be successfully uninstalled.
+*/
+RUNNER_TEST(ace_registration_tests_03)
+{
+    RUNNER_ASSERT_MSG(uninstall(tizenId), "Failed to uninstall widget!");
+}
diff --git a/tests/general/BackgroundPageTests.cpp b/tests/general/BackgroundPageTests.cpp
new file mode 100644 (file)
index 0000000..b996cbe
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013 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  Karol Pawlowski (k.pawlowski@samsung.com)
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief   Background page installation test's bodies
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(BackgroundPage)
+
+/*
+Name: widgetWithBackgroundPage
+Description: Tests if widget with background page is installed correctly
+Expected: widget should be installed correctly
+*/
+RUNNER_TEST(widgetWithBackgroundPage)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/bg-00-with_bg.wgt",
+            tizenId) == InstallerWrapper::Success);
+    uninstall(tizenId);
+}
+
+/*
+Name: missingBackgroundFile
+Description: Tests if widget with declared in conifg background page
+ but missing background file will be installed correctly.
+Expected: widget should NOT be installed
+*/
+RUNNER_TEST(missingBackgroundFile)
+{
+    std::string tizenId;
+    if(install(miscWidgetsStuff + "widgets/bg-01-missing_file.wgt",
+            tizenId) == InstallerWrapper::Success) {
+        uninstall(tizenId);
+        RUNNER_ASSERT_MSG(false, "Invalid widget package installed");
+    }
+}
+
+/*
+Name: widgetWithoutBackgroundPage
+Description: Complementary test to check if normal widget\
+ without background page is successfully installed
+Expected: widget should be installed
+*/
+RUNNER_TEST(widgetWithoutBackgroundPage)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/bg-02-without_bg.wgt",
+            tizenId) == InstallerWrapper::Success);
+    uninstall(tizenId);
+}
diff --git a/tests/general/CMakeLists.txt b/tests/general/CMakeLists.txt
new file mode 100644 (file)
index 0000000..05a4161
--- /dev/null
@@ -0,0 +1,181 @@
+# Copyright (c) 2013 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      Karol Pawlowski (k.pawlowski@samsung.com)
+#
+
+PKG_CHECK_MODULES(COMMON_LIB_PKGS
+    dbus-1
+    libpcrecpp
+    dpl-efl
+    dpl-test-efl
+    dpl-utils-efl
+    dpl-wrt-dao-ro
+    dpl-event-efl
+    cert-svc-vcore
+    xmlsec1
+    libiri
+    REQUIRED
+    )
+
+pkg_search_module(dpl REQUIRED dpl-efl)
+pkg_search_module(dpl-test REQUIRED dpl-test-efl)
+
+SET(WRT_TEST_LIBRARY "wrt-tests-libs")
+
+include_directories(
+  ${dpl_INCLUDE_DIRS}
+  ${dpl-test_INCLUDE_DIRS}
+  ${ace-client_INCLUDE_DIRS}
+)
+
+SET(COMMON_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}")
+
+SET_PROPERTY(GLOBAL APPEND PROPERTY COMMON_TESTS_LIBRARY ${WRT_TEST_LIBRARY})
+
+SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_INCLUDE_DIRS ${COMMON_LIB_PKGS_INCLUDE_DIRS})
+
+SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARY_DIRS ${COMMON_LIB_PKGS_LIBRARY_DIRS})
+
+SET_PROPERTY(GLOBAL APPEND PROPERTY TESTS_LIBRARIES ${COMMON_LIB_PKGS_LIBRARIES})
+
+SET(WRT_DETAIL_SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/InstallerWrapper.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ManifestFile.cpp
+)
+
+INCLUDE_DIRECTORIES(${COMMON_INCLUDES})
+INCLUDE_DIRECTORIES(${COMMON_LIB_PKGS_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(SYSTEM ${SYS_INSTALLER_STATIC_DEP_INCLUDE_DIRS})
+
+ADD_LIBRARY(${WRT_TEST_LIBRARY} STATIC ${WRT_DETAIL_SOURCES})
+
+
+SET(INSTALLER_TESTS_TARGET "wrt-installer-tests-general")
+
+PKG_CHECK_MODULES(INSTALLER_TESTS_DEPS
+    wrt-commons-i18n-dao-ro
+    REQUIRED)
+
+SET(INSTALLER_TESTS_SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/TestInit.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ManifestTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/BackgroundPageTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/NPluginsInstallTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingAccountTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingAllowNavigationTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingAppWidgetTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingCategoryTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingContentTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingCspTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingMetadataTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingTizenAppcontrolTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingTizenPrivilegeTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParsingSplashImgTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/WidgetUpdateTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/PluginsInstallation.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/LanguageSubtagRstTreeTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/WidgetInstallManifestTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/WidgetLocationTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/AceRegistrationTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/ParserRunnerTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/TaskConfigurationTests.cpp
+    ${CMAKE_SOURCE_DIR}/src/wrt-installer/language_subtag_rst_tree.cpp
+    ${CMAKE_SOURCE_DIR}/src/wrt-installer/installer_callbacks_translate.cpp
+)
+
+SET(INSTALLER_TESTS_INCLUDE_DIRS
+    ${INSTALLER_TESTS_DEPS_INCLUDE_DIRS}
+    ${CMAKE_SOURCE_DIR}/src/wrt-installer
+    ${CMAKE_SOURCE_DIR}/src/configuration_parser
+    ${CMAKE_SOURCE_DIR}/src/commons
+    ${CMAKE_SOURCE_DIR}/src/jobs
+    ${CMAKE_SOURCE_DIR}/src/jobs/widget_install
+    ${CMAKE_SOURCE_DIR}/src
+    ${CMAKE_SOURCE_DIR}/src/misc
+    ${CMAKE_SOURCE_DIR}/src/pkg-manager
+)
+
+# Functions used to build test targets (proper sources, includes, libs are
+# added automatically)
+FUNCTION(WRT_TEST_BUILD TARGET_NAME)
+    # get include dirs global property
+    GET_PROPERTY(INCLUDE_DIRS GLOBAL PROPERTY TESTS_INCLUDE_DIRS)
+    GET_PROPERTY(TEST_INCLUDE_DIRS GLOBAL PROPERTY ${TARGET_NAME}_INCLUDE_DIRS)
+    INCLUDE_DIRECTORIES(
+        ${INCLUDE_DIRS}
+        ${TEST_INCLUDE_DIRS}
+    )
+
+    # get library dirs global property
+    GET_PROPERTY(LIBRARY_DIRS GLOBAL PROPERTY TESTS_LIBRARY_DIRS)
+    GET_PROPERTY(TEST_LIBRARY_DIRS GLOBAL PROPERTY ${TARGET_NAME}_LIBRARY_DIRS)
+    LINK_DIRECTORIES(
+        ${LIBRARY_DIRS}
+        ${TEST_LIBRARY_DIRS}
+    )
+
+    SET(SOURCES "${ARGN}")
+    ADD_EXECUTABLE("${TARGET_NAME}" ${SOURCES})
+
+    # get link libraries global property
+    GET_PROPERTY(LINK_LIBRARIES GLOBAL PROPERTY TESTS_LIBRARIES)
+    GET_PROPERTY(TEST_LIBRARIES GLOBAL PROPERTY ${TARGET_NAME}_LIBRARIES)
+    TARGET_LINK_LIBRARIES("${TARGET_NAME}"
+        ${LINK_LIBRARIES}
+        ${TEST_LIBRARIES}
+    )
+ENDFUNCTION(WRT_TEST_BUILD)
+
+FUNCTION(WRT_TEST_INSTALL)
+    SET_TARGET_PROPERTIES(${ARGV} PROPERTIES
+        BUILD_WITH_INSTALL_RPATH ON
+        INSTALL_RPATH_USE_LINK_PATH ON
+    )
+    INSTALL(TARGETS ${ARGV}
+        DESTINATION bin
+        PERMISSIONS OWNER_READ
+                    OWNER_WRITE
+                    OWNER_EXECUTE
+                    GROUP_READ
+                    GROUP_EXECUTE
+                    WORLD_READ
+                    WORLD_EXECUTE
+    )
+ENDFUNCTION(WRT_TEST_INSTALL)
+
+FUNCTION(WRT_TEST_INCLUDE_DIRS TARGET_NAME)
+    SET_PROPERTY(GLOBAL APPEND PROPERTY ${TARGET_NAME}_INCLUDE_DIRS ${ARGN})
+ENDFUNCTION(WRT_TEST_INCLUDE_DIRS)
+
+WRT_TEST_INCLUDE_DIRS(${INSTALLER_TESTS_TARGET} ${INSTALLER_TESTS_INCLUDE_DIRS})
+WRT_TEST_BUILD(${INSTALLER_TESTS_TARGET} ${INSTALLER_TESTS_SOURCES})
+WRT_TEST_INSTALL(${INSTALLER_TESTS_TARGET})
+target_link_libraries(${INSTALLER_TESTS_TARGET}
+  ${dpl_LIBRARIES}
+  ${dpl-test_LIBRARIES}
+  ${WRT_TEST_LIBRARY}
+  ${TARGET_CORE_MODULE_LIB}
+  ${COMMON_LIB_PKGS_LIBRARIES}
+  ${INSTALLER_TESTS_DEPS_LIBRARIES}
+  ${TARGET_INSTALLER_STATIC}
+)
+
+#widgets
+FILE(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/widgets/*.wgt")
+INSTALL(FILES ${files} "${CMAKE_CURRENT_SOURCE_DIR}/widgets/widgetInDir.tar" DESTINATION /opt/share/widget/tests/installer/widgets/)
+
+FILE(GLOB files_conf "${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xml")
+INSTALL(FILES ${files_conf} DESTINATION /opt/share/widget/tests/installer/configs/)
diff --git a/tests/general/InstallerWrapper.cpp b/tests/general/InstallerWrapper.cpp
new file mode 100644 (file)
index 0000000..de98a3f
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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 "InstallerWrapper.h"
+
+#include <installer_log.h>
+
+#include <cstdio>
+
+namespace
+{
+
+const std::string params = "DPL_USE_OLD_STYLE_LOGS=0 "
+    "DPL_USE_OLD_STYLE_PEDANTIC_LOGS=0 WRT_TEST_MODE=1 ";
+const std::string installCmd = params + "wrt-installer -i ";
+const std::string uninstallCmd = params + "wrt-installer -un ";
+const std::string redirection =  " 2>&1";
+const std::string INSTALLER_MESSAGE_ID_LINE =
+    "## wrt-installer : %s installation was successful.\n";
+const std::string INSTALLER_MESSAGE_ID_LINE_FAIL =
+    "## wrt-installer : %s installation has failed - package already installed";
+const std::string INSTALLER_MESSSGE_START = "## wrt-installer : ";
+
+std::string getAndCutInstallerLogLine(std::string &src)
+{
+    size_t startIndex = src.find(INSTALLER_MESSSGE_START);
+    if (startIndex == std::string::npos)
+    {
+        _W("Installer message can not be found");
+        return std::string();
+    }
+    size_t newLineIndex = src.find("\n", startIndex);
+    std::string line = src.substr(startIndex, newLineIndex - startIndex + 1);
+    src.erase(0, newLineIndex + 1);
+    return line;
+}
+
+}
+
+namespace InstallerWrapper
+{
+
+InstallResult install(
+        const std::string& path,
+        std::string& tizenId,
+        const std::string& user)
+{
+    std::string msg;
+
+    auto cmd = installCmd + path + redirection;
+    if(user.length()) //if other user should be used
+    {
+        cmd = "su " + user + " -c '" + cmd + "'";
+    }
+    auto filehandle = popen(cmd.c_str(), "r");
+    if (!filehandle) {;
+        return OtherError;
+    }
+
+    char buffer[1024] = "";
+    while ( fread_unlocked(buffer, sizeof(char),
+            sizeof(buffer)/sizeof(char), filehandle) > 0 )
+    {
+        msg += buffer;
+    }
+    _D("%s", msg.c_str());
+    auto err = pclose(filehandle);
+    if (!WIFEXITED(err)) {
+        return OtherError;
+    }
+
+    char* id = NULL;
+    std::string line;
+
+    if (0 != WEXITSTATUS(err)) {
+        while ((line = getAndCutInstallerLogLine(msg)) != "")
+        {
+            if(line.find("failed") != std::string::npos)
+            {
+                id = new char[line.length()];
+                int nr = sscanf(line.c_str(), INSTALLER_MESSAGE_ID_LINE_FAIL.c_str(), id);
+                if (1 != nr)
+                {
+                    _W("Can not read widget ID from message: %s", line.c_str());
+                    delete[] id;
+                    return OtherError;
+                }
+                tizenId = id;
+                delete[] id;
+            }
+        }
+
+        if (1 == WEXITSTATUS(err)) {
+            return WrongWidgetPackage;
+        }
+        return OtherError;
+    }
+
+    while ((line = getAndCutInstallerLogLine(msg)) != "")
+    {
+        if (line.find("successful") != std::string::npos)
+        {
+            id = new char[line.length()];
+            int nr = sscanf(line.c_str(), INSTALLER_MESSAGE_ID_LINE.c_str(), id);
+
+            if (1 != nr)
+            {
+                _W("Can not read widget ID from message: %s", line.c_str());
+                delete[] id;
+                return OtherError;
+            }
+            tizenId = id;
+            delete[] id;
+            if (tizenId != "plugin")
+            {
+                return Success;
+            }
+        }
+    }
+
+    return OtherError;
+}
+
+bool uninstall(const std::string& tizenId)
+{
+    std::string cmd = uninstallCmd + tizenId + " > /dev/null 2>/dev/null";
+    _D("executing: %s", cmd.c_str());
+    return (system(cmd.c_str()) == EXIT_SUCCESS);
+}
+
+bool sigintWrtClients()
+{
+    return (system("pkill -2 wrt-client") == 0);
+}
+
+}
+
diff --git a/tests/general/InstallerWrapper.h b/tests/general/InstallerWrapper.h
new file mode 100644 (file)
index 0000000..404a3e8
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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_INSTALLER_TESTS_GENERAL_INSTALLER_WRAPPER_H
+#define WRT_INSTALLER_TESTS_GENERAL_INSTALLER_WRAPPER_H
+
+#include <string>
+
+namespace InstallerWrapper
+{
+
+typedef int InstallResult;
+const InstallResult WrongWidgetPackage = -2;
+const InstallResult OtherError = -1;
+const InstallResult Success = 0;
+
+const std::string miscWidgetsStuff = "/opt/share/widget/tests/installer/";
+
+struct Result {
+    bool m_exc;
+    bool m_exd;
+    bool m_exs;
+    std::string message;
+    Result(bool exc = false, bool exd = false, bool exs = false)
+        : m_exc(exc), m_exd(exd), m_exs(exs) {}
+};
+
+InstallResult install(
+        const std::string& path,
+        std::string& tizenId,
+        const std::string& user = "");
+bool uninstall(const std::string& tizenId);
+/**
+ * @brief killWrtClients kills processes that matches 'wrt-client'
+ * @return True if any client was killed
+ */
+bool sigintWrtClients();
+
+}
+
+#endif//WRT_INSTALLER_TESTS_GENERAL_INSTALLER_WRAPPER_H
diff --git a/tests/general/LanguageSubtagRstTreeTests.cpp b/tests/general/LanguageSubtagRstTreeTests.cpp
new file mode 100644 (file)
index 0000000..bd05f87
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 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    LanguageSubtagRstTreeTests.cpp
+ * @author  Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
+ * @version 1.0
+ * @brief   Language tags tests
+ */
+
+#include <dpl/test/test_runner.h>
+#include <language_subtag_rst_tree.h>
+
+namespace {
+const char LANGUAGE_TAG_VALID[] = "en-us";
+const char LANGUAGE_TAG_INVALID[] = "invalid0";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(LanguageSubtagRstTree)
+
+/*
+Name: ValidateLanguageTag_Valid
+Description: tests result returned for valid language tag
+Expected: value true should be returned
+*/
+RUNNER_TEST(ValidateLanguageTag_Valid)
+{
+  RUNNER_ASSERT(LanguageSubtagRstTreeSingleton::Instance().
+          ValidateLanguageTag(LANGUAGE_TAG_VALID));
+}
+
+/*
+Name: ValidateLanguageTag_Invalid
+Description: tests result returned for invalid language tag
+Expected: value false should be returned
+*/
+RUNNER_TEST(ValidateLanguageTag_Invalid)
+{
+  RUNNER_ASSERT(!LanguageSubtagRstTreeSingleton::Instance().
+          ValidateLanguageTag(LANGUAGE_TAG_INVALID));
+}
diff --git a/tests/general/ManifestFile.cpp b/tests/general/ManifestFile.cpp
new file mode 100644 (file)
index 0000000..2206c2a
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012 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        ManifestFile.cpp
+ * @author      Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief       Manifest file reading
+ */
+
+#include <ManifestFile.h>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <installer_log.h>
+
+//TODO: This file reads manifest file. This functionality is familiar with writing
+//      in wrt-installer but reading ws not necessary there.
+//      Maybe it should be changed in some way.
+
+ManifestFile::ManifestFile(const std::string & file) : filename(file)
+{
+    xmlXPathInit();
+    parse();
+}
+
+ManifestFile::~ManifestFile()
+{
+    xmlXPathFreeContext(xpathCtx);
+    xmlFreeDoc(doc);
+}
+
+void ManifestFile::parse()
+{
+    doc = xmlReadFile(filename.c_str(), NULL, 0);
+    if (doc == NULL)
+    {
+        ThrowMsg(ManifestParseError,"File Problem");
+    }
+    else
+    {
+        //context
+        xpathCtx = xmlXPathNewContext(doc);
+        if(xpathCtx == NULL)
+        {
+            ThrowMsg(ManifestParseError,"Error: unable to create new XPath context\n");
+        }
+        xpathCtx->node = xmlDocGetRootElement(doc);
+
+        if(xmlXPathRegisterNs(xpathCtx, BAD_CAST "p", BAD_CAST "http://tizen.org/ns/packages") != 0)
+        {
+            ThrowMsg(ManifestParseError,"Error: unable to register namespace\n");
+        }
+    }
+}
+
+std::string ManifestFile::getValueByXpath(const std::string & path) const
+{
+    std::string result;
+    xmlXPathObjectPtr xpathObject;
+    //get requested node's values
+    xpathObject = xmlXPathEvalExpression(BAD_CAST path.c_str(), xpathCtx);
+    if(xpathObject == NULL)
+    {
+        ThrowMsg(ManifestParseError,"XPath evaluation failure: " << path);
+    }
+    xmlNodeSetPtr nodes = xpathObject->nodesetval;
+    int size = (nodes) ? nodes->nodeNr : 0;
+    if(size != 1)
+    {
+        ThrowMsg(ManifestParseError,"Xpath does not point 1 element but " << size
+                 << " for xpath: " << path);
+    }
+    else
+    {
+        if(nodes->nodeTab[0]->type == XML_ELEMENT_NODE)
+        {
+            xmlNodePtr cur = nodes->nodeTab[0];
+            xmlChar * value = xmlNodeGetContent(cur);
+            result = std::string(reinterpret_cast<char*>(value)); //this cast should be safe...
+            xmlFree(value);
+        }
+        else if(nodes->nodeTab[0]->type == XML_ATTRIBUTE_NODE)
+        {
+            xmlNodePtr cur = nodes->nodeTab[0];
+            xmlChar * value = xmlNodeGetContent(cur);
+            result = std::string(reinterpret_cast<char*>(value));
+            xmlFree(value);
+        }
+    }
+    //Cleanup of XPath data
+    xmlXPathFreeObject(xpathObject);
+    return result;
+}
diff --git a/tests/general/ManifestFile.h b/tests/general/ManifestFile.h
new file mode 100644 (file)
index 0000000..ccb6a7b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012 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        ManifestFile.h
+ * @author      Tomasz Iwanek (t.iwanek@samsung.com)
+ * @brief       Manifest file reading
+ */
+
+#ifndef WRT_INSTALLER_TESTS_GENERAL_MANIFESTFILE_H
+#define WRT_INSTALLER_TESTS_GENERAL_MANIFESTFILE_H
+
+#include <string>
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <dpl/exception.h>
+
+/**
+ * @brief The ManifestFile class which serialize xml file to tree
+ */
+class ManifestFile
+{
+public:
+    DECLARE_EXCEPTION_TYPE(DPL::Exception,Base)
+    DECLARE_EXCEPTION_TYPE(Base,ManifestParseError)
+
+    ManifestFile(const std::string & file);
+    ~ManifestFile();
+
+    std::string getValueByXpath(const std::string & path) const;
+private:
+    void parse();
+
+    std::string filename;
+    xmlDocPtr doc;
+    xmlXPathContextPtr xpathCtx;
+};
+
+
+#endif //WRT_INSTALLER_TESTS_GENERAL_MANIFESTFILE_H
diff --git a/tests/general/ManifestTests.cpp b/tests/general/ManifestTests.cpp
new file mode 100644 (file)
index 0000000..4e316da
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2013 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  Karol Pawlowski (k.pawlowski@samsung.com)
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief   Manifest installation test's bodies
+ */
+
+#include <string>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+#include <installer_log.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(Manifest)
+
+/*
+Name: creatingManifestFile
+Description: Creation of manifest file by wrt-installer test
+Expected: file should be created and installed by wrt-installer. Content should
+ match expected values
+*/
+RUNNER_TEST(creatingManifestFile)
+{
+    std::string manifestPath = "/opt/share/packages/";
+    /* This widget removal should stay here in case previous test run failed
+     * (so widget has not been uninstalled) */
+    std::string tizenId;
+
+    if(install(miscWidgetsStuff + "widgets/manifest.wgt", tizenId)
+            != InstallerWrapper::Success)
+    {
+        uninstall(tizenId);
+        RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/manifest.wgt", tizenId)
+                == InstallerWrapper::Success);
+    }
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestPath.append(tizenId.substr(0,10)).append(".xml")));
+    ManifestFile mf(manifestPath);
+
+    Try
+    {
+        _D("Package %s", mf.getValueByXpath("/p:manifest/@package").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/@package")
+                      == tizenId.substr(0,10));
+        _D("type %s", mf.getValueByXpath("/p:manifest/@type").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/@type")
+                      == "wgt");
+        _D("version %s", mf.getValueByXpath("/p:manifest/@version").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/@version")
+                      == "1.0");
+        _D("label %s", mf.getValueByXpath("/p:manifest/p:label").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:label")
+                      == "Manifest Example");
+
+        _D("email %s", mf.getValueByXpath("/p:manifest/p:author/@email").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:author/@email")
+                      == "manifest@misc.test.create.desktop.com");
+        _D("href %s", mf.getValueByXpath("/p:manifest/p:author/@href").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:author/@href")
+                      == "http://misc.test.create.desktop.com");
+        _D("author %s", mf.getValueByXpath("/p:manifest/p:author").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:author")
+                      == "Manifest");
+
+        _D("appid %s", mf.getValueByXpath("/p:manifest/p:ui-application/@appid").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@appid")
+                      == tizenId);
+        _D("type %s", mf.getValueByXpath("/p:manifest/p:ui-application/@type").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@type")
+                      == "webapp");
+        _D("extraid %s", mf.getValueByXpath("/p:manifest/p:ui-application/@extraid").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/@extraid")
+                      == "http://test.samsung.com/widget/manifestTest");
+        _D("icon %s", mf.getValueByXpath("/p:manifest/p:ui-application/p:icon").c_str());
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:icon")
+                      == (std::string(WrtDB::GlobalConfig::GetUserInstalledWidgetPath()) + "/" + tizenId.substr(0,10) + WrtDB::GlobalConfig::GetWidgetSharedPath() + WrtDB::GlobalConfig::GetWidgetResPath() + "/" + tizenId + ".png"));
+
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[not(@xml:lang)]")
+                      == "Manifest Example");
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='de-de']")
+                      == "Manifest Beispiel");
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='en-us']")
+                      == "Manifest Example");
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='pl']")
+                      == "PrzykÅ‚ad Manifest");
+        RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:label[@xml:lang='pt-pt']")
+                      == "Exemplo manifesto");
+    }
+    Catch(ManifestFile::ManifestParseError)
+    {
+        RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+    }
+    /* If test finished sucessfully than uninstall test widget */
+    uninstall(tizenId);
+}
diff --git a/tests/general/NPluginsInstallTests.cpp b/tests/general/NPluginsInstallTests.cpp
new file mode 100644 (file)
index 0000000..ac141d8
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013 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  Karol Pawlowski (k.pawlowski@samsung.com)
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief   NPlugins installation test's bodies
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(NPluginsInstall)
+
+/*
+Name: pluginFilesAdded
+Description: Tests installation of plugins attached to widget
+Expected: widget should be succesfully installed
+*/
+RUNNER_TEST(pluginFilesAdded)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff
+            + "widgets/inst_nplug_1.wgt", tizenId) == InstallerWrapper::Success);
+    uninstall(tizenId);
+}
+
+/*
+Name: pluginFileAndOtherFile
+Description: Tests installation with plugins directory and data files
+Expected: widget should be installed
+*/
+RUNNER_TEST(pluginFileAndOtherFile)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff
+            + "widgets/inst_nplug_3.wgt", tizenId) == InstallerWrapper::Success);
+    uninstall(tizenId);
+}
diff --git a/tests/general/ParserRunnerTests.cpp b/tests/general/ParserRunnerTests.cpp
new file mode 100644 (file)
index 0000000..e87d90f
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2014 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    ParserRunnerTests.cpp
+ * @author  Adrian Szafranek (a.szafranek@samsung.com)
+ * @version 1.0
+ * @brief   Perform ParserRunner test's.
+ */
+
+#include <parser_runner.h>
+#include <dpl/scope_guard.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/utils/path.h>
+
+#include <installer_log.h>
+
+#include <string>
+#include <fstream>
+#include <cstdio>
+#include <memory>
+
+RUNNER_TEST_GROUP_INIT(ParserRunner)
+
+using namespace DPL::Utils;
+
+namespace {
+const std::string rootTest = "/tmp/";
+const std::string schemaFile = "/usr/etc/wrt-installer/widgets.xsd";
+const std::string configFile = "/usr/lib/wrt-plugins/tizen-content/config.xml";
+const std::string installConfigFile = "/opt/share/widget/tests/installer/configs/InstallConfig.xml";
+}
+
+class StreamRedirector
+{
+    public:
+    StreamRedirector(FILE* src, std::string dest)
+        : source(src), file_dest(dest)
+    {
+        fd = dup(fileno(source));
+        if ((fd < 0) || (freopen(file_dest.c_str(), "w", source) == NULL))
+        {
+            _D("Error catching stream.");
+        }
+    }
+    ~StreamRedirector()
+    {
+        if (TEMP_FAILURE_RETRY(fflush(source)) == 0)
+        {
+            if (dup2(fd, fileno(source)) >= 0)
+            {
+                close(fd);
+                clearerr(source);
+            }
+            else
+            {
+                _D("Error returning stream.");
+            }
+        }
+        else
+        {
+            _D("Error returning stream.");
+        }
+    }
+
+    private:
+    FILE* source;
+    std::string file_dest;
+    int fd;
+};
+
+
+/*
+Name: parserRunner01
+Description: Tests validation and parsing functionality.
+Test performed for proper files existing in system, wrong files or empty parameters.
+*/
+RUNNER_TEST(parserRunner01)
+{
+    ParserRunner parser;
+
+    std::unique_ptr<StreamRedirector> sd(new StreamRedirector(stderr, "/dev/null"));
+
+
+    if (Path(installConfigFile).Exists() && Path(schemaFile).Exists()) {
+        RUNNER_ASSERT(parser.Validate(installConfigFile, schemaFile) == true);
+    }
+
+    if (Path(configFile).Exists() && Path(schemaFile).Exists()) {
+        RUNNER_ASSERT(parser.Validate(configFile, schemaFile) == false);
+    }
+
+    RUNNER_ASSERT(parser.Validate("", "") == false);
+}
+
+/*
+Name: parserRunner02
+Description: Tests validation and parsing functionality.
+Test performed for wrong 'xml', empty 'xsd' file and wrong 'xml', non empty 'xsd' file.
+*/
+RUNNER_TEST(parserRunner02)
+{
+    ParserRunner parser;
+
+    std::unique_ptr<StreamRedirector> sd(new StreamRedirector(stderr, "/dev/null"));
+
+
+    Path pathF1 = Path(rootTest + "testFile1.xml");
+    if (!pathF1.Exists()) {
+        MakeEmptyFile(pathF1);
+
+        DPL_SCOPE_EXIT(&pathF1) { TryRemove(pathF1); };
+
+        std::ofstream ofs1;
+        ofs1.open(pathF1.Fullpath(), std::ofstream::out);
+        if (!ofs1) {
+            RUNNER_ASSERT_MSG(false, "Error creating file");
+        }
+        ofs1 << "wrongContent";
+        ofs1.close();
+
+        RUNNER_ASSERT(parser.Validate(pathF1.Fullpath(), "") == false);
+        if (Path(schemaFile).Exists()) {
+            RUNNER_ASSERT(parser.Validate(pathF1.Fullpath(), schemaFile) == false);
+        }
+    }
+}
+
+/*
+Name: parserRunner03
+Description: Tests validation and parsing functionality.
+Test performed for empty 'xml', wrong 'xsd' file and non empty 'xml', wrong 'xsd' file.
+*/
+RUNNER_TEST(parserRunner03)
+{
+    ParserRunner parser;
+
+    std::unique_ptr<StreamRedirector> sd(new StreamRedirector(stderr, "/dev/null"));
+
+
+    Path pathF2 = Path(rootTest + "testFile2.xsd");
+    if (!pathF2.Exists()) {
+        MakeEmptyFile(pathF2);
+
+        DPL_SCOPE_EXIT(&pathF2) { TryRemove(pathF2); };
+
+        std::ofstream ofs2;
+        ofs2.open(pathF2.Fullpath(), std::ofstream::out);
+        if (!ofs2) {
+            RUNNER_ASSERT_MSG(false, "Error creating file");
+        }
+        ofs2 << "<element name=\"Test\" type=\"ds:TransformType\"/>";
+        ofs2.close();
+
+        RUNNER_ASSERT(parser.Validate("", pathF2.Fullpath()) == false);
+        if (Path(configFile).Exists()) {
+            RUNNER_ASSERT(parser.Validate(configFile, pathF2.Fullpath()) == false);
+        }
+    }
+}
diff --git a/tests/general/ParsingAccountTests.cpp b/tests/general/ParsingAccountTests.cpp
new file mode 100644 (file)
index 0000000..f19e52b
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014 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    ParsingAccountTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   Account element installation tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingAccount)
+
+/*
+Name: InstallWidgetWithAccount
+Description: Tests if widget with account is installed correctly
+Expected: widget should be installed correctly and account information should be present in manifest file
+*/
+RUNNER_TEST(InstallWidgetWithAccount)
+{
+    std::string tizenId;
+    std::string manifestPath = "/opt/share/packages/";
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/account.wgt", tizenId) == InstallerWrapper::Success);
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestPath.append(tizenId.substr(0, 10)).append(".xml")));
+    ManifestFile mf(manifestPath);
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/@multiple-accounts-support") == "true");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:icon[1]/@section") == "account");
+    std::string iconPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()) + WrtDB::GlobalConfig::GetWidgetSharedPath() +
+                WrtDB::GlobalConfig::GetWidgetResPath() + "/";
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:icon[1]") == iconPath + "icon1.png");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:icon[2]/@section") == "account-small");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:icon[2]") == iconPath + "icon2.png");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:label[1]") == "Name1");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:label[2]/@xml:lang") == "en-US");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:label[2]") == "Name2");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:capability[1]") == "http://tizen.org/account/capability/contact");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:account/p:account-provider/p:capability[2]") == "http://tizen.org/account/capability/calendar");
+    uninstall(tizenId);
+}
diff --git a/tests/general/ParsingAllowNavigationTests.cpp b/tests/general/ParsingAllowNavigationTests.cpp
new file mode 100644 (file)
index 0000000..f5e219c
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2013 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    ParsingAllowNavigationTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   allow-navigation element installation tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+namespace{
+
+struct AllowNavigationComparator {
+    AllowNavigationComparator(const DPL::String & scheme, const DPL::String& host) :
+            m_scheme(scheme), m_host(host){}
+    const DPL::String m_scheme;
+    const DPL::String m_host;
+    bool operator()(const WrtDB::ConfigParserData::AllowNavigationInfo& navs) const
+    {
+        return navs.m_host == m_host && navs.m_scheme == m_scheme;
+    }
+    bool operator()(const WrtDB::WidgetAllowNavigationInfo& navs) const
+    {
+        return navs.host == m_host && navs.scheme == m_scheme;
+    }
+};
+
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingAllowNavigation)
+
+/*
+Name: InstallWidgetWithAllowNavigation
+Description: Tests if widget with allow-navigation is installed correctly
+Expected: widget should be installed correctly and allowNavigation info should be stored in database
+*/
+RUNNER_TEST(InstallWidgetWithAllowNavigation)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/allowNavigation.wgt", tizenId) == InstallerWrapper::Success);
+
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+    WrtDB::WidgetAllowNavigationInfoList allowNavigationList;
+    dao.getWidgetAllowNavigationInfo(allowNavigationList);
+
+    uninstall(tizenId);
+
+    RUNNER_ASSERT(allowNavigationList.size() == 4);
+    RUNNER_ASSERT(1 == std::count_if(allowNavigationList.begin(), allowNavigationList.end(),
+            AllowNavigationComparator(L"http",L"test2.org")));
+    RUNNER_ASSERT(1 == std::count_if(allowNavigationList.begin(), allowNavigationList.end(),
+            AllowNavigationComparator(L"*",L"test3.org")));
+    RUNNER_ASSERT(1 == std::count_if(allowNavigationList.begin(), allowNavigationList.end(),
+            AllowNavigationComparator(L"*",L"*.test4.org")));
+    RUNNER_ASSERT(1 == std::count_if(allowNavigationList.begin(), allowNavigationList.end(),
+            AllowNavigationComparator(L"*",L"*")));
+}
+
+
+/*
+Name: NoAllowNavigation
+Description: Tests parsing configuration file without allow-navigation element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(NoAllowNavigation)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/NoAllowNavigation.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(0 == widgetConfig.allowNavigationInfoList.size());
+}
+
+/*
+Name: AllowNavigationEmpty
+Description: Tests parsing configuration file with empty allow-navigation element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(AllowNavigationEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AllowNavigationEmpty.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(0 == widgetConfig.allowNavigationInfoList.size());
+}
+
+/*
+Name: MultipleAllowNavigation
+Description: Tests parsing configuration file with multiple allow-navigation element
+Expected: Element should be parsed correctly. Only values from first element should be stored
+*/
+RUNNER_TEST(MultipleAllowNavigation)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/MultipleAllowNavigation.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.allowNavigationInfoList.size());
+    RUNNER_ASSERT(L"*" == widgetConfig.allowNavigationInfoList.begin()->m_scheme);
+    RUNNER_ASSERT(L"test1.org" == widgetConfig.allowNavigationInfoList.begin()->m_host);
+}
+
+/*
+Name: AllowNavigationMultipleHosts
+Description: Tests parsing configuration file with multiple values in allow-navigation element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(AllowNavigationMultipleHosts)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AllowNavigationMultipleHosts.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(4 == widgetConfig.allowNavigationInfoList.size());
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"http",L"test2.org")));
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"*",L"test3.org")));
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"*",L"*.test4.org")));
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"*",L"*")));
+}
+
+/*
+Name: AllowNavigationMultipleHosts
+Description: Tests parsing configuration file with multiple values in allow-navigation element
+             with special characters like \n and \t
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(AllowNavigationMultipleHostsMultiline)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AllowNavigationMultipleHostsMultiline.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(4 == widgetConfig.allowNavigationInfoList.size());
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"http",L"test2.org")));
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"*",L"test3.org")));
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"*",L"*.test4.org")));
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.allowNavigationInfoList.begin(), widgetConfig.allowNavigationInfoList.end(),
+            AllowNavigationComparator(L"*",L"*")));
+}
diff --git a/tests/general/ParsingAppWidgetTests.cpp b/tests/general/ParsingAppWidgetTests.cpp
new file mode 100644 (file)
index 0000000..6fbc2df
--- /dev/null
@@ -0,0 +1,1043 @@
+/*
+ * Copyright (c) 2013 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    ParsingAppWidgetTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   Parsing Tizen app-widget bodies
+ */
+
+#include <string>
+#include <algorithm>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+namespace{
+
+template<typename Exception, typename Function>
+bool checkException(Function fun)
+{
+    Try
+    {
+        fun();
+    }
+    Catch(Exception){
+        return true;
+    }
+    return false;
+}
+
+} // namespace
+
+#define RUNNER_ASSERT_EXCEPTION(exceptionType, function)             \
+    {                                                                \
+        RUNNER_ASSERT(checkException<exceptionType>([&](){function})); \
+    }
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingAppWidget)
+
+/*
+Name: InstallWidgetWithAppWidgetFull
+Description: Tests if app-widget tag is correctly parsed when all children are included
+Expected: widget should be installed. All information should be stored in manifest file
+*/
+RUNNER_TEST(InstallWidgetWithAppWidgetFull)
+{
+    std::string manifestPath = "/opt/share/packages/";
+
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/appWidgetFull.wgt", tizenId) == InstallerWrapper::Success);
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestPath.append(tizenId.substr(0, 10)).append(".xml")));
+    ManifestFile mf(manifestPath);
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/@appid") == "jeyk39ehc8.appwidget.default");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/@primary") == "true");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/@period") == "1800.0");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:launch") == "true");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:label") == "My DynamicBox");
+    std::string iconPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()) + WrtDB::GlobalConfig::GetWidgetSharedPath() +
+            WrtDB::GlobalConfig::GetWidgetDataPath() + "/" + tizenId + ".default.icon.png";
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:icon") == iconPath);
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/@mouse_event") == "false");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/@touch_effect") == "false");
+    std::string boxSrcPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()) + WrtDB::GlobalConfig::GetWidgetSrcPath()
+            + "/app-widget/index.html";
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/p:script/@src") == boxSrcPath);
+    std::string boxPreviewPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()) + WrtDB::GlobalConfig::GetWidgetSharedPath() +
+            WrtDB::GlobalConfig::GetWidgetDataPath() + "/" + tizenId + ".default.1x1.preview.png";
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/p:size/@preview") == boxPreviewPath);
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/p:size/@need_frame") == "false");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/p:size") == "1x1");
+    std::string pdSrcPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()) + WrtDB::GlobalConfig::GetWidgetSrcPath()
+            + "/pd/index.html";
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:pd/p:script/@src") == pdSrcPath);
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:pd/p:size") == "720x150");
+
+    RUNNER_ASSERT(uninstall(tizenId));
+}
+
+/*
+Name: InstallWidgetWithAppWidgetMinimal
+Description: Tests if app-widget tag is correctly parsed when only mandatory children are included
+Expected: widget should be installed. All information should be stored in manifest file
+*/
+RUNNER_TEST(InstallWidgetWithAppWidgetMinimal)
+{
+    std::string manifestPath = "/opt/share/packages/";
+
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/appWidgetMinimal.wgt", tizenId) == InstallerWrapper::Success);
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestPath.append(tizenId.substr(0, 10)).append(".xml")));
+    ManifestFile mf(manifestPath);
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/@appid") == "djel94jdl9.appwidget.default");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/@primary") == "true");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:label") == "My DynamicBox");
+    std::string boxSrcPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()) + WrtDB::GlobalConfig::GetWidgetSrcPath()
+            + "/app-widget/index.html";
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/p:script/@src") == boxSrcPath);
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:livebox/p:box/p:size") == "1x1");
+
+    RUNNER_ASSERT(uninstall(tizenId));
+}
+
+/*
+Name: InstallWidgetWithAppWidgetIncorrect
+Description: Tests widget installation when app-widget Id and application Id are different
+Expected: widget should not be installed.
+*/
+RUNNER_TEST(InstallWidgetWithAppWidgetIncorrect)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/appWidgetIncorrect.wgt", tizenId) != InstallerWrapper::Success);
+}
+
+
+/*
+Name: AppWidgetFull
+Description: Tests parsing app-widget element with all children
+Expected: Elements should be parsed correctly.
+*/
+RUNNER_TEST(AppWidgetFull)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetFull.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"tizenScmgz.Sample.default" == (**widgetConfig.m_livebox.begin()).m_liveboxId);
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_primary);
+    RUNNER_ASSERT(L"1800.0" == (**widgetConfig.m_livebox.begin()).m_updatePeriod);
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_autoLaunch);
+    RUNNER_ASSERT(L"My DynamicBox" == (**widgetConfig.m_livebox.begin()).m_label.begin()->second);
+    RUNNER_ASSERT(L"box-icon.png" == (**widgetConfig.m_livebox.begin()).m_icon);
+    RUNNER_ASSERT(L"app-widget/index.html" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSrc);
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxMouseEvent);
+    RUNNER_ASSERT(L"false" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxTouchEffect);
+    RUNNER_ASSERT(1 == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.size());
+    RUNNER_ASSERT(L"app-widget/preview-lb1-11.png" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_preview);
+    RUNNER_ASSERT(L"false" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_useDecoration);
+    RUNNER_ASSERT(L"1x1" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_size);
+    RUNNER_ASSERT(L"pd/index.html" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdSrc);
+    RUNNER_ASSERT(L"720" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdWidth);
+    RUNNER_ASSERT(L"150" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdHeight);
+}
+
+
+/*
+Name: AppWidgetMinimal
+Description: Tests parsing app-widget element with mandatory children
+Expected: Elements should be parsed correctly.
+*/
+RUNNER_TEST(AppWidgetMinimal)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetMinimal.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"tizenScmgz.Sample.default" == (**widgetConfig.m_livebox.begin()).m_liveboxId);
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_primary);
+    RUNNER_ASSERT(L"My DynamicBox" == (**widgetConfig.m_livebox.begin()).m_label.begin()->second);
+    RUNNER_ASSERT(L"app-widget/index.html" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSrc);
+    RUNNER_ASSERT(L"1x1" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_size);
+}
+
+/*
+Name: AppWidgetIdTooShort
+Description: Tests parsing app-widget element with too short id
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetIdTooShort)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetIdTooShort.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetIdTooLong
+Description: Tests parsing app-widget element with too long id
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetIdTooLong)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetIdTooLong.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetIdWrongChar
+Description: Tests parsing app-widget element with ill-formed id
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetIdWrongChar)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetIdWrongChar.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetIdEmpty
+Description: Tests parsing app-widget element with empty id
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetIdEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetIdEmpty.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetNoId
+Description: Tests parsing app-widget element without id
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetNoId)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetNoId.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetPrimaryWrongValue
+Description: Tests parsing app-widget element with wrong primary argument
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetPrimaryWrongValue)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetPrimaryWrongValue.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetPrimaryEmpty
+Description: Tests parsing app-widget element with empty primary argument
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetPrimaryEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetPrimaryEmpty.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetNoPrimary
+Description: Tests parsing app-widget element without primary argument
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetNoPrimary)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetNoPrimary.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetMultiplePrimary
+Description: Tests parsing configuration with multiple app-widget element.
+Expected: Parsing should be successful.
+*/
+RUNNER_TEST(AppWidgetMultiplePrimary)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetMultiplePrimary.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(3 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(2 == std::count_if(widgetConfig.m_livebox.begin(), widgetConfig.m_livebox.end(),
+            [](const WrtDB::ConfigParserData::OptionalLiveboxInfo& liveBox){
+                return liveBox->m_primary == L"true";
+            })
+    );
+    RUNNER_ASSERT(1 == std::count_if(widgetConfig.m_livebox.begin(), widgetConfig.m_livebox.end(),
+            [](const WrtDB::ConfigParserData::OptionalLiveboxInfo& liveBox){
+                return liveBox->m_primary == L"false";
+            })
+    );
+}
+
+/*
+Name: AppWidgetUpdatePeriodLow
+Description: Tests parsing app-widget element with update-period argument too low
+Expected: Parsing should be successful. updatePeriod should have low boundary value.
+*/
+RUNNER_TEST(AppWidgetUpdatePeriodLow)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetUpdatePeriodLow.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"1800.0" == (**widgetConfig.m_livebox.begin()).m_updatePeriod);
+}
+
+/*
+Name: AppWidgetUpdatePeriodWrongFormat
+Description: Tests parsing app-widget element with wrong update-period argument.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetUpdatePeriodWrongFormat)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetUpdatePeriodWrongFormat.xml",
+                        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+             );
+}
+
+/*
+Name: AppWidgetUpdatePeriodEmpty
+Description: Tests parsing app-widget element with empty update-period argument.
+Expected: Parsing should be successful. updatePeriod should have empty value.
+*/
+RUNNER_TEST(AppWidgetUpdatePeriodEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetUpdatePeriodEmpty.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT((**widgetConfig.m_livebox.begin()).m_updatePeriod.empty());
+}
+
+/*
+Name: RUNNER_TEST(AppWidgetAutoLaunchWrongValue)
+Description: Tests parsing app-widget element with wrong auto-launch argument.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetAutoLaunchWrongValue)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+            parser.Parse(miscWidgetsStuff + "configs/AppWidgetAutoLaunchWrongValue.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+            );
+}
+
+/*
+Name: AppWidgetAutoLaunchEmpty
+Description: Tests parsing app-widget element with empty auto-launch argument.
+Expected: Parsing should be successful. auto-launch should have empty value.
+*/
+RUNNER_TEST(AppWidgetAutoLaunchEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetAutoLaunchEmpty.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"false" == (**widgetConfig.m_livebox.begin()).m_autoLaunch);
+}
+
+/*
+Name: BoxLabelEmpty
+Description: Tests parsing empty box-label element.
+Expected: Parsing should be successful. label should have empty value.
+*/
+RUNNER_TEST(BoxLabelEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxLabelEmpty.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(1 == (**widgetConfig.m_livebox.begin()).m_label.size());
+    RUNNER_ASSERT((**widgetConfig.m_livebox.begin()).m_label.begin()->first.empty());
+    RUNNER_ASSERT((**widgetConfig.m_livebox.begin()).m_label.begin()->second.empty());
+}
+
+/*
+Name: AppWidgetNoBoxLabel
+Description: Tests parsing app-widget element without box-label element.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetNoBoxLabel)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/AppWidgetNoBoxLabel.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: AppWidgetMultipleBoxLabel
+Description: Tests parsing app-widget element with multiple box-label element.
+Expected: Parsing should be successful and elements stored correctly.
+*/
+RUNNER_TEST(AppWidgetMultipleBoxLabel)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/AppWidgetMultipleBoxLabel.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(3 == (**widgetConfig.m_livebox.begin()).m_label.size());
+
+    RUNNER_ASSERT(
+       1 == std::count((**widgetConfig.m_livebox.begin()).m_label.begin(), (**widgetConfig.m_livebox.begin()).m_label.end(),
+            std::pair<DPL::String, DPL::String>(L"en",L"test_en") ));
+    RUNNER_ASSERT(
+        1 == std::count((**widgetConfig.m_livebox.begin()).m_label.begin(), (**widgetConfig.m_livebox.begin()).m_label.end(),
+                std::pair<DPL::String, DPL::String>(L"pl",L"test_pl") ));
+    RUNNER_ASSERT(
+        1 == std::count((**widgetConfig.m_livebox.begin()).m_label.begin(), (**widgetConfig.m_livebox.begin()).m_label.end(),
+                std::pair<DPL::String, DPL::String>(L"",L"test") ));
+
+}
+
+/*
+Name: BoxIconEmpty
+Description: Tests parsing empty box-icon element.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxIconEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxIconEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxIconSrcEmpty
+Description: Tests parsing box-icon element with empty src attribute.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxIconSrcEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxIconSrcEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: AppWidgetMultipleBoxIcon
+Description: Tests parsing app-widget with multiple box-icon elements.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetMultipleBoxIcon)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/AppWidgetMultipleBoxIcon.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: AppWidgetNoBoxContent
+Description: Tests parsing app-widget without box-content element.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetNoBoxContent)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/AppWidgetNoBoxContent.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+
+/*
+Name: AppWidgetMultipleBoxContent
+Description: Tests parsing app-widget with multiple box-content element.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(AppWidgetMultipleBoxContent)
+{
+
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/AppWidgetMultipleBoxContent.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+
+/*
+Name: BoxContentEmpty
+Description: Tests parsing empty box-content element.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxContentEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxContentEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxContentNoSrc
+Description: Tests parsing box-content element without src attribute.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxContentNoSrc)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxContentNoSrc.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxContentSrcEmpty
+Description: Tests parsing box-content element with empty src attribute.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxContentSrcEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxContentSrcEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxContentNoMouseEvent
+Description: Tests parsing box-content element without mouse-event attribute.
+Expected: Parsing should be successful. boxMouseEvent should have default value.
+*/
+RUNNER_TEST(BoxContentNoMouseEvent)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxContentNoMouseEvent.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"false" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxMouseEvent);
+}
+
+/*
+Name: BoxContentMouseEventEmpty
+Description: Tests parsing box-content element with empty mouse-event attribute.
+Expected: Parsing should be successful. boxMouseEvent should have default value.
+*/
+RUNNER_TEST(BoxContentMouseEventEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxContentMouseEventEmpty.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"false" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxMouseEvent);
+}
+
+/*
+Name: BoxContentMouseEventWrongValue
+Description: Tests parsing box-content element with wrong mouse-event attribute.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxContentMouseEventWrongValue)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxContentMouseEventWrongValue.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxContentNoTouchEfect
+Description: Tests parsing box-content element without touch-effect attribute.
+Expected: Parsing should be successful. boxTouchEffect should have default value.
+*/
+RUNNER_TEST(BoxContentNoTouchEfect)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxContentNoTouchEfect.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxTouchEffect);
+}
+
+/*
+Name: BoxContentTouchEfectEmpty
+Description: Tests parsing box-content element with empty touch-effect attribute.
+Expected: Parsing should be successful. boxTouchEffect should have default value.
+*/
+RUNNER_TEST(BoxContentTouchEfectEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxContentTouchEfectEmpty.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxTouchEffect);
+}
+
+/*
+Name: BoxContentTouchEfectWrongValue
+Description: Tests parsing box-content element with wrong touch-effect attribute.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxContentTouchEfectWrongValue)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxContentTouchEfectWrongValue.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxContentMultipleBoxSize
+Description: Tests parsing box-content element with multiple box-size elements.
+Expected: Parsing should be successful.
+*/
+RUNNER_TEST(BoxContentMultipleBoxSize)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxContentMultipleBoxSize.xml",
+           ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(3 == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.size());
+
+    RUNNER_ASSERT(1 == std::count_if((**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin(),
+            (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.end(),
+            [](const WrtDB::ConfigParserData::LiveboxInfo::BoxSizeInfo& boxSize){
+                return boxSize.m_size == L"1x1";
+            })
+    );
+    RUNNER_ASSERT(1 == std::count_if((**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin(),
+            (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.end(),
+            [](const WrtDB::ConfigParserData::LiveboxInfo::BoxSizeInfo& boxSize){
+                return boxSize.m_size == L"2x1";
+            })
+    );
+    RUNNER_ASSERT(1 == std::count_if((**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin(),
+            (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.end(),
+            [](const WrtDB::ConfigParserData::LiveboxInfo::BoxSizeInfo& boxSize){
+                return boxSize.m_size == L"2x2";
+            })
+    );
+}
+
+/*
+Name: BoxSizeEmpty
+Description: Tests parsing empty box-size element.
+Expected: Exception should be thrown.
+*/
+RUNNER_TEST(BoxSizeEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxSizeEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: BoxSizePreviewEmpty
+Description: Tests parsing box-size element with empty preview attribute.
+Expected: Parsing should be successful. Preview value should be empty
+*/
+RUNNER_TEST(BoxSizePreviewEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxSizePreviewEmpty.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(1 == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.size());
+    RUNNER_ASSERT((**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_preview.empty());
+}
+
+/*
+Name: BoxSizeNoUserDecoration
+Description: Tests parsing box-size element without use-decoration attribute.
+Expected: Parsing should be successful. useDecoration should be set to default value
+*/
+RUNNER_TEST(BoxSizeNoUserDecoration)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxSizeNoUserDecoration.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(1 == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.size());
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_useDecoration);
+}
+
+/*
+Name: BoxSizeUserDecorationEmpty
+Description: Tests parsing box-size element with empty use-decoration attribute.
+Expected: Parsing should be successful. useDecoration should be set to default value
+*/
+RUNNER_TEST(BoxSizeUserDecorationEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/BoxSizeUserDecorationEmpty.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(1 == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.size());
+    RUNNER_ASSERT(L"true" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_boxSize.begin()->m_useDecoration);
+}
+
+/*
+Name: BoxContentMultiplePd
+Description: Tests parsing box-content element with multiple pd element.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(BoxContentMultiplePd)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/BoxContentMultiplePd.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdNoSrc
+Description: Tests parsing pd element without src attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdNoSrc)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdNoSrc.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdSrcEmpty
+Description: Tests parsing pd element with empty src attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdSrcEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdSrcEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdNoWidth
+Description: Tests parsing pd element without width attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdNoWidth)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdNoWidth.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdWidthEmpty
+Description: Tests parsing pd element with empty width attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdWidthEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdWidthEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdWidthZero
+Description: Tests parsing pd element with width zero value.
+Expected: Parsing should be successful.
+*/
+RUNNER_TEST(PdWidthZero)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/PdWidthZero.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"0" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdWidth);
+}
+
+/*
+Name: PdWidthNegative
+Description: Tests parsing pd element with width negative value.
+Expected: Parsing should be successful.
+*/
+RUNNER_TEST(PdWidthNegative)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/PdWidthNegative.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"-1" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdWidth);
+}
+
+/*
+Name: PdWidthWrongValue
+Description: Tests parsing pd element with width wrong value.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdWidthWrongValue)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdWidthWrongValue.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdNoHeight
+Description: Tests parsing pd element without height attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdNoHeight)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdNoHeight.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdHeightEmpty
+Description: Tests parsing pd element with empty height attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdHeightEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdHeightEmpty.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: PdHeightTooLow
+Description: Tests parsing pd element with height attribute below range.
+Expected: Parsing should be successful. Height should have low boundary value.
+*/
+RUNNER_TEST(PdHeightTooLow)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/PdHeightTooLow.xml",
+       ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"1" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdHeight);
+}
+
+/*
+Name: PdHeightExcessive
+Description: Tests parsing pd element with height attribute with value above range.
+Expected: Parsing should be successful. Height should have high boundary value.
+*/
+RUNNER_TEST(PdHeightExcessive)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/PdHeightExcessive.xml",
+       ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(1 == widgetConfig.m_livebox.size());
+    RUNNER_ASSERT(L"380" == (**widgetConfig.m_livebox.begin()).m_boxInfo.m_pdHeight);
+}
+
+/*
+Name: PdHeightWrongValue
+Description: Tests parsing pd element with wrong height attribute.
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(PdHeightWrongValue)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/PdHeightWrongValue.xml",
+                ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
diff --git a/tests/general/ParsingCategoryTests.cpp b/tests/general/ParsingCategoryTests.cpp
new file mode 100644 (file)
index 0000000..a376807
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013 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    ParsingCategoryTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   Category element installation tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+#include <dpl/utils/wrt_utility.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingCategory)
+
+/*
+Name: InstallWidgetWithCategory
+Description: Tests if widget with category is installed correctly
+Expected: widget should be installed correctly and category should be present in manifest file
+*/
+RUNNER_TEST(InstallWidgetWithCategory)
+{
+    std::string tizenId;
+    std::string manifestPath = "/opt/share/packages/";
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/category.wgt", tizenId) == InstallerWrapper::Success);
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestPath.append(tizenId.substr(0, 10)).append(".xml")));
+    ManifestFile mf(manifestPath);
+
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:category[1]/@name") == "testCategory");
+    uninstall(tizenId);
+}
+
+
+/*
+Name: CategoryElementOk
+Description: Tests parsing correct category element
+Expected: Element should be parsed correcty.
+*/
+RUNNER_TEST(CategoryElementOk)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_category1.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(2 == widgetConfig.categoryList.size());
+    RUNNER_ASSERT(std::count(widgetConfig.categoryList.begin(), widgetConfig.categoryList.end(), L"testCategory1") == 1);
+    RUNNER_ASSERT(std::count(widgetConfig.categoryList.begin(), widgetConfig.categoryList.end(), L"testCategory2") == 1);
+}
+
+/*
+Name: CategoryElementEmptyName
+Description: Tests parsing splash element with empty name attribute
+Expected: No exception and categoryList should be empty
+*/
+RUNNER_TEST(CategoryElementEmptyName)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_category2.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(widgetConfig.categoryList.empty());
+}
+
+/*
+Name: CategoryElementNoName
+Description: Tests parsing category element with no name attribute
+Expected: No exception and categoryList should be empty
+*/
+RUNNER_TEST(CategoryElementNoName)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_category3.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(widgetConfig.categoryList.empty());
+}
+
+/*
+Name: CategoryElementDuplicated
+Description: Tests parsing three category elements (two are identical)
+Expected: No exception and categoryList should have two distinct elements
+*/
+RUNNER_TEST(CategoryElementDuplicated)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_category4.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(2 == widgetConfig.categoryList.size());
+    RUNNER_ASSERT(std::count(widgetConfig.categoryList.begin(), widgetConfig.categoryList.end(), L"testCategory1") == 1);
+    RUNNER_ASSERT(std::count(widgetConfig.categoryList.begin(), widgetConfig.categoryList.end(), L"testCategory2") == 1);
+
+}
diff --git a/tests/general/ParsingContentTests.cpp b/tests/general/ParsingContentTests.cpp
new file mode 100644 (file)
index 0000000..56b114e
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2014 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    ParsingContentTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   content element installation tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+namespace{
+
+template<typename Exception, typename Function>
+bool checkException(Function fun)
+{
+    Try
+    {
+        fun();
+    }
+    Catch(Exception){
+        return true;
+    }
+    return false;
+}
+
+} // namespace
+
+#define RUNNER_ASSERT_EXCEPTION(exceptionType, function)             \
+    {                                                                \
+        RUNNER_ASSERT(checkException<exceptionType>([&](){function})); \
+    }
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingContent)
+
+/*
+Name: InstallWidgetWithContentCorrect
+Description: Tests if widget with correct content element is installed correctly
+Expected: widget should be installed correctly and startFile info should be stored in database
+*/
+RUNNER_TEST(InstallWidgetWithContentCorrect)
+{
+    std::string tizenId;
+    std::string manifestPath = "/opt/share/packages/";
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/contentCorrect.wgt", tizenId) == InstallerWrapper::Success);
+
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+    WrtDB::WidgetDAOReadOnly::WidgetStartFileList startFileList = dao.getStartFileList();
+
+    RUNNER_ASSERT(6 == startFileList.size());
+    RUNNER_ASSERT(
+       1 == std::count_if(startFileList.begin(), startFileList.end(),
+               [](const WrtDB::WidgetDAOReadOnly::WidgetStartFileRow& startFileRow){
+                   return L"http://test.org" == startFileRow.src;
+               })
+       );
+
+
+    uninstall(tizenId);
+}
+
+/*
+Name: InstallWidgetWithContentIncorrect
+Description: Tests if widget with incorrect content element is not installed correctly
+Expected: widget should not be installed
+*/
+RUNNER_TEST(InstallWidgetWithContentIncorrect)
+{
+    std::string tizenId;
+    std::string manifestPath = "/opt/share/packages/";
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/contentIncorrect.wgt", tizenId) == InstallerWrapper::OtherError);
+}
+
+/*
+Name: NoContent
+Description: Tests parsing configuration file without content element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(NoContent)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/NoContent.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(widgetConfig.metadataList.empty());
+}
+
+/*
+Name: ContentEmpty
+Description: Tests parsing configuration file with empty content element
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(ContentEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/ContentEmpty.xml",
+                ElementParserPtr( new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: ContentSrcEmpty
+Description: Tests parsing configuration file with empty src attribute in content element
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(ContentSrcEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/ContentSrcEmpty.xml",
+                ElementParserPtr( new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
+
+/*
+Name: ContentSrcCorrect
+Description: Tests parsing configuration file with correct content element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(ContentSrcCorrect)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/ContentSrcCorrect.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(DPL::OptionalString(L"http://test.org") == widgetConfig.startFile);
+}
+
+/*
+Name: MultipleContentCorrect
+Description: Tests parsing configuration file with multiple content element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(MultipleContentCorrect)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/MultipleContentCorrect.xml",
+        ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(DPL::OptionalString(L"http://test.org") == widgetConfig.startFile);
+}
+
+/*
+Name: MultipleContentCorrect
+Description: Tests parsing configuration file with multiple content element.
+            First occurrence is incorrect
+Expected: Exception should be thrown
+*/
+RUNNER_TEST(MultipleContentIncorrect)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+        parser.Parse(miscWidgetsStuff + "configs/MultipleContentIncorrect.xml",
+                ElementParserPtr( new RootParser<WidgetParser>(widgetConfig, L"widget")));
+    );
+}
diff --git a/tests/general/ParsingCspTests.cpp b/tests/general/ParsingCspTests.cpp
new file mode 100644 (file)
index 0000000..0dcbf3e
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2013 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    ParsingCspTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   content-security-policy and content-security-policy-report-only element installation
+ *          tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingCsp)
+
+/*
+Name: InstallWidgetWithCsp
+Description: Tests if widget with content-security-policy and content-security-policy-report-only is installed correctly
+Expected: widget should be installed correctly and CSP values should be correctly stored in database
+*/
+RUNNER_TEST(InstallWidgetWithCsp)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/csp.wgt", tizenId) == InstallerWrapper::Success);
+
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+
+    RUNNER_ASSERT(L"testCSP" == *dao.getCspPolicy());
+    RUNNER_ASSERT(L"testCSPro" == *dao.getCspPolicyReportOnly());
+
+    uninstall(tizenId);
+}
+
+
+/*
+Name: NoCsp
+Description: Tests parsing configuration file without content-security-policy and content-security-policy-report-only element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(NoCsp)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/NoCsp.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(!widgetConfig.cspPolicy);
+    RUNNER_ASSERT(!widgetConfig.cspPolicyReportOnly);
+}
+
+/*
+Name: CspEmpty
+Description: Tests parsing configuration file with empty content-security-policy element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(CspEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/CspEmpty.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(!widgetConfig.cspPolicy);
+    RUNNER_ASSERT(!widgetConfig.cspPolicyReportOnly);
+}
+
+/*
+Name: CspReportOnlyEmpty
+Description: Tests parsing configuration file with empty content-security-policy-report-only element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(CspReportOnlyEmpty)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/CspReportOnlyEmpty.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(!widgetConfig.cspPolicy);
+    RUNNER_ASSERT(!widgetConfig.cspPolicyReportOnly);
+}
+
+/*
+Name: MultipleCsp
+Description: Tests parsing configuration file with multiple content-security-policy  elements
+Expected: Element should be parsed correctly. Only values from first element should be stored
+*/
+RUNNER_TEST(MultipleCsp)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/MultipleCsp.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(L"testCSP" == *widgetConfig.cspPolicy);
+}
+
+/*
+Name: MultipleCsp
+Description: Tests parsing configuration file with multiple content-security-policy-report-only  elements
+Expected: Element should be parsed correctly. Only values from first element should be stored
+*/
+RUNNER_TEST(MultipleCspReportOnly)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/MultipleCspReportOnly.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(L"testCSP" == *widgetConfig.cspPolicyReportOnly);
+}
diff --git a/tests/general/ParsingMetadataTests.cpp b/tests/general/ParsingMetadataTests.cpp
new file mode 100644 (file)
index 0000000..a3a0818
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2013 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    ParsingMetadataTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   metadata element installation tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+#include <dpl/utils/wrt_utility.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+namespace{
+
+template<typename Exception, typename Function>
+bool checkException(Function fun)
+{
+    Try
+    {
+        fun();
+    }
+    Catch(Exception){
+        return true;
+    }
+    return false;
+}
+
+} // namespace
+
+#define RUNNER_ASSERT_EXCEPTION(exceptionType, function)             \
+    {                                                                \
+        RUNNER_ASSERT(checkException<exceptionType>([&](){function})); \
+    }
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingMetadata)
+
+/*
+Name: InstallWidgetWithMetadata
+Description: Tests if widget with metadata element is installed correctly
+Expected: widget should be installed correctly and metadata info should be stored in manifest file
+*/
+RUNNER_TEST(InstallWidgetWithMetadata)
+{
+    std::string tizenId;
+    std::string manifestPath = "/opt/share/packages/";
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/metadata.wgt", tizenId) == InstallerWrapper::Success);
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestPath.append(tizenId.substr(0, 10)).append(".xml")));
+    ManifestFile mf(manifestPath);
+
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:metadata[1]/@key") == "key1");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:metadata[2]/@key") == "key2");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:metadata[2]/@value") == "value2");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:metadata[3]/@key") == "key3");
+    RUNNER_ASSERT(mf.getValueByXpath("/p:manifest/p:ui-application/p:metadata[3]/@value") == "value3");
+    uninstall(tizenId);
+}
+
+
+/*
+Name: NoMetadata
+Description: Tests parsing configuration file without metadata element
+Expected: Element should be parsed correctly.
+*/
+RUNNER_TEST(NoMetadata)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/NoMetadata.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(widgetConfig.metadataList.empty());
+}
+
+/*
+Name: MetadataEmpty
+Description: Tests parsing configuration file with empty metadata element
+Expected: Exception should be thrown
+*/
+//TODO: Fix in parser needed
+//RUNNER_TEST(MetadataEmpty)
+//{
+//    ParserRunner parser;
+//    WrtDB::ConfigParserData widgetConfig;
+//
+//    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+//        parser.Parse(miscWidgetsStuff + "configs/MetadataEmpty.xml",
+//                ElementParserPtr( new RootParser<WidgetParser>(widgetConfig, L"widget")));
+//    );
+//}
+
+/*
+Name: MultipleMetadata
+Description: Tests parsing configuration file with multiple metadata element
+Expected: Element should be parsed correctly. All values should be stored
+*/
+RUNNER_TEST(MultipleMetadata)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/MultipleMetadata.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(3 == widgetConfig.metadataList.size());
+
+    RUNNER_ASSERT(1 == std::count(widgetConfig.metadataList.begin(), widgetConfig.metadataList.end(),
+            WrtDB::ConfigParserData::Metadata(DPL::OptionalString(L"key1"), DPL::OptionalString())));
+    RUNNER_ASSERT(1 == std::count(widgetConfig.metadataList.begin(), widgetConfig.metadataList.end(),
+            WrtDB::ConfigParserData::Metadata(DPL::OptionalString(L"key2"), DPL::OptionalString(L"value2"))));
+    RUNNER_ASSERT(1 == std::count(widgetConfig.metadataList.begin(), widgetConfig.metadataList.end(),
+            WrtDB::ConfigParserData::Metadata(DPL::OptionalString(L"key3"), DPL::OptionalString(L"value3"))));
+
+}
+
+/*
+Name: MetadataDuplicatedKey
+Description: Tests parsing configuration file with duplicated key attribute value in metadata element
+Expected: Exception should be thrown
+*/
+//TODO: Fix in parser needed
+//RUNNER_TEST(MetadataDuplicatedKey)
+//{
+//    ParserRunner parser;
+//    WrtDB::ConfigParserData widgetConfig;
+//
+//    RUNNER_ASSERT_EXCEPTION(ElementParser::Exception::ParseError,
+//        parser.Parse(miscWidgetsStuff + "configs/MetadataDuplicatedKey.xml",
+//                ElementParserPtr( new RootParser<WidgetParser>(widgetConfig, L"widget")));
+//    );
+//}
diff --git a/tests/general/ParsingSplashImgTests.cpp b/tests/general/ParsingSplashImgTests.cpp
new file mode 100644 (file)
index 0000000..0e550f7
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2013 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    ParsingSplashImgTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   Splash element installation tests
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingSplashImg)
+
+/*
+Name: InstallWidgetWithSplash
+Description: Tests if widget with splash is installed correctly
+Expected: widget should be installed correctly and splashImg registered in database
+*/
+RUNNER_TEST(InstallWidgetWithSplash)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/splash.wgt", tizenId) == InstallerWrapper::Success);
+
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+
+    RUNNER_ASSERT(*dao.getWidgetInstalledPath() + L"/res/wgt/splash.html" == *dao.getSplashImgSrc());
+
+    uninstall(tizenId);
+}
+
+
+/*
+Name: SplashElementOk
+Description: Tests parsing correct splash element
+Expected: Element should be parsed correcty.
+*/
+RUNNER_TEST(SplashElementOk)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_splash1.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                        L"widget")));
+
+    RUNNER_ASSERT(DPL::OptionalString(L"splash.html") == widgetConfig.splashImgSrc);
+}
+
+/*
+Name: SplashElementEmptySrc
+Description: Tests parsing splash element with empty src attribute
+Expected: No exception and splash should be null
+*/
+RUNNER_TEST(SplashElementEmptySrc)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_splash2.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(!widgetConfig.splashImgSrc);
+}
+
+/*
+Name: SplashElementNoSrc
+Description: Tests parsing splash element with no src attribute
+Expected: No exception and splash should be null
+*/
+RUNNER_TEST(SplashElementNoSrc)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_splash3.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(!widgetConfig.splashImgSrc);
+
+}
+
+/*
+Name: SplashElementNoNamespace
+Description: Tests parsing splash element without tizen namespace
+Expected: No exception and splash should be null
+*/
+RUNNER_TEST(SplashElementNoNamespace)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_splash4.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(!widgetConfig.splashImgSrc);
+
+}
diff --git a/tests/general/ParsingTizenAppcontrolTests.cpp b/tests/general/ParsingTizenAppcontrolTests.cpp
new file mode 100644 (file)
index 0000000..299354f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2013 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  Karol Pawlowski (k.pawlowski@samsung.com)
+ * @author  Andrzej Surdej (a.surdej@samsung.com)
+ * @version 1.0
+ * @brief   Parsing Tizen app-control test's bodies
+ */
+
+#include <string>
+#include <algorithm>
+#include <dpl/test/test_runner.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <InstallerWrapper.h>
+#include <installer_log.h>
+
+using namespace InstallerWrapper;
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingTizenAppcontrol)
+
+/*
+Name: tizen_app-contro
+Description: Tests if widget app-control tag is correctly parsed
+Expected: widget should be installed
+*/
+RUNNER_TEST(tizen_app_control)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/app-control.wgt",
+            tizenId) == InstallerWrapper::Success);
+
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+    WrtDB::WidgetAppControlList appcontrolList;
+    dao.getAppControlList(appcontrolList);
+    uninstall(tizenId);
+
+    _D("Actual size %d", appcontrolList.size());
+    RUNNER_ASSERT_MSG(appcontrolList.size() == 4, "Incorrect list size");
+    WrtDB::WidgetAppControl s;
+    s.src = DPL::FromUTF8String("edit1.html");
+    s.operation = DPL::FromUTF8String("http://tizen.org/appcontrol/operation/edit");
+    s.mime = DPL::FromUTF8String("image/jpg");      /* mime type */
+    s.disposition = WrtDB::WidgetAppControl::Disposition::WINDOW;
+
+    RUNNER_ASSERT_MSG(
+        std::find(appcontrolList.begin(), appcontrolList.end(), s) != appcontrolList.end(),
+        "Unable to find service #");
+
+    s.src = DPL::FromUTF8String("edit2.html");
+    s.operation = DPL::FromUTF8String("http://tizen.org/appcontrol/operation/view");
+    s.mime = DPL::FromUTF8String("audio/ogg");      /* mime type */
+    s.disposition = WrtDB::WidgetAppControl::Disposition::WINDOW;
+
+    RUNNER_ASSERT_MSG(
+        std::find(appcontrolList.begin(), appcontrolList.end(), s) != appcontrolList.end(),
+        "Unable to find service ##");
+
+    s.src = DPL::FromUTF8String("edit3.html");
+    s.operation = DPL::FromUTF8String("http://tizen.org/appcontrol/operation/call");
+    s.mime = DPL::FromUTF8String("image/png");      /* mime type */
+    s.disposition = WrtDB::WidgetAppControl::Disposition::WINDOW;
+
+    RUNNER_ASSERT_MSG(
+        std::find(appcontrolList.begin(), appcontrolList.end(), s) != appcontrolList.end(),
+        "Unable to find service ###");
+
+    s.src = DPL::FromUTF8String("edit4.html");
+    s.operation = DPL::FromUTF8String("http://tizen.org/appcontrol/operation/send");
+    s.mime = DPL::FromUTF8String("text/css");      /* mime type */
+    s.disposition = WrtDB::WidgetAppControl::Disposition::WINDOW;
+
+    RUNNER_ASSERT_MSG(
+        std::find(appcontrolList.begin(), appcontrolList.end(), s) != appcontrolList.end(),
+        "Unable to find service ####");
+}
diff --git a/tests/general/ParsingTizenPrivilegeTests.cpp b/tests/general/ParsingTizenPrivilegeTests.cpp
new file mode 100644 (file)
index 0000000..1cf2032
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2013 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    ParsingTizenPrivilegeTests.cpp
+ * @author  Slawomir Pajak (s.pajak@partner.samsung.com)
+ * @version 1.0
+ * @brief   Parsing Tizen privilege bodies
+ */
+
+#include <string>
+#include <algorithm>
+#include <dpl/test/test_runner.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <InstallerWrapper.h>
+
+#include <root_parser.h>
+#include <widget_parser.h>
+#include <parser_runner.h>
+
+using namespace InstallerWrapper;
+
+namespace {
+
+class CompareFeatureByName {
+public:
+    CompareFeatureByName(DPL::String name) :
+            m_name(name)
+    {
+
+    }
+    bool operator()(const WrtDB::DbWidgetFeature& feature)
+    {
+        return feature.name == m_name;
+    }
+private:
+    DPL::String m_name;
+};
+
+}
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(ParsingTizenPrivilege)
+
+/*
+Name: tizen_privilege
+Description: Tests if widget privilege tag is correctly parsed
+Expected: widget should be installed. Privileges and features registered in database
+*/
+RUNNER_TEST(InstallWidgetWithPrivilege)
+{
+    std::string tizenId;
+    RUNNER_ASSERT(install(miscWidgetsStuff + "widgets/privilege.wgt", tizenId) == InstallerWrapper::Success);
+
+    WrtDB::WidgetDAOReadOnly dao(DPL::FromASCIIString(tizenId));
+    WrtDB::PrivilegeList privilegeList = dao.getWidgetPrivilege();
+    WrtDB::DbWidgetFeatureSet featureList = dao.getFeaturesList();
+    uninstall(tizenId);
+
+    RUNNER_ASSERT(privilegeList.size() == 5);
+    RUNNER_ASSERT(std::count(privilegeList.begin(), privilegeList.end(), L"http://tizen.org/privilege/location") == 1);
+    RUNNER_ASSERT(
+            std::count(privilegeList.begin(), privilegeList.end(), L"http://tizen.org/privilege/notification") == 1);
+    RUNNER_ASSERT(
+            std::count(privilegeList.begin(), privilegeList.end(), L"http://tizen.org/privilege/mediacapture") == 1);
+    RUNNER_ASSERT(
+            std::count(privilegeList.begin(), privilegeList.end(), L"http://tizen.org/privilege/fullscreen") == 1);
+    RUNNER_ASSERT(
+            std::count(privilegeList.begin(), privilegeList.end(), L"http://tizen.org/privilege/unlimitedstorage") == 1);
+
+    RUNNER_ASSERT(featureList.size() == 5);
+    RUNNER_ASSERT(
+            std::count_if(featureList.begin(), featureList.end(), CompareFeatureByName(L"http://tizen.org/privilege/location")) == 1);
+    RUNNER_ASSERT(
+            std::count_if(featureList.begin(), featureList.end(), CompareFeatureByName(L"http://tizen.org/privilege/notification")) == 1);
+    RUNNER_ASSERT(
+            std::count_if(featureList.begin(), featureList.end(), CompareFeatureByName(L"http://tizen.org/privilege/mediacapture")) == 1);
+    RUNNER_ASSERT(
+            std::count_if(featureList.begin(), featureList.end(), CompareFeatureByName(L"http://tizen.org/privilege/fullscreen")) == 1);
+    RUNNER_ASSERT(
+            std::count_if(featureList.begin(), featureList.end(), CompareFeatureByName(L"http://tizen.org/privilege/unlimitedstorage")) == 1);
+}
+
+/*
+Name: PrivilegeElementOk
+Description: Tests parsing correct privilege element
+Expected: Element should be parsed correcty.
+*/
+RUNNER_TEST(PrivilegeElementOk)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_privilege1.xml",
+            ElementParserPtr(new RootParser<WidgetParser>(widgetConfig, L"widget")));
+
+    RUNNER_ASSERT(5 == widgetConfig.privilegeList.size());
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/location")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/notification")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/mediacapture")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/fullscreen")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/unlimitedstorage")) == 1);
+
+    RUNNER_ASSERT(5 == widgetConfig.featuresList.size());
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/location")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/notification")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/mediacapture")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/fullscreen")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/unlimitedstorage")) == 1);
+}
+
+/*
+Name: CategoryElementEmptyName
+Description: Tests parsing privilege element with empty name attribute
+Expected: No exception. PrivilegeList and featuresList should be empty
+*/
+RUNNER_TEST(PrivilegeElementEmptyName)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_privilege2.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(widgetConfig.privilegeList.empty());
+    RUNNER_ASSERT(widgetConfig.featuresList.empty());
+}
+
+/*
+Name: PrivilegeElementNoName
+Description: Tests parsing privilege element with no name attribute
+Expected: No exception. PrivilegeList and featuresList should be empty
+*/
+RUNNER_TEST(PrivilegeElementNoName)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_privilege3.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(widgetConfig.categoryList.empty());
+    RUNNER_ASSERT(widgetConfig.featuresList.empty());
+}
+
+/*
+Name: PrivilegeElementNoNameSpace
+Description: Tests parsing privilege element without proper namespace
+Expected: No exception. PrivilegeList and featuresList should be empty
+*/
+RUNNER_TEST(PrivilegeElementNoNameSpace)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_privilege4.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(widgetConfig.categoryList.empty());
+    RUNNER_ASSERT(widgetConfig.featuresList.empty());
+}
+
+/*
+Name: PrivilegeElementDuplicated
+Description: Tests parsing three privilege elements (two are identical)
+Expected: No exception. PrivilegeList and featuresList should have two distinct elements
+*/
+RUNNER_TEST(PrivilegeElementDuplicated)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_privilege5.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(2 == widgetConfig.privilegeList.size());
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/location")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.privilegeList.begin(), widgetConfig.privilegeList.end(),
+                    WrtDB::ConfigParserData::Privilege(L"http://tizen.org/privilege/notification")) == 1);
+
+    RUNNER_ASSERT(2 == widgetConfig.featuresList.size());
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/location")) == 1);
+    RUNNER_ASSERT(
+            std::count(widgetConfig.featuresList.begin(), widgetConfig.featuresList.end(),
+                    WrtDB::ConfigParserData::Feature(L"http://tizen.org/privilege/notification")) == 1);
+
+}
+
+/*
+Name: PrivilegeElementWrongFormat
+Description: Tests parsing privilege elements with wrong format
+Expected: No exception. PrivilegeList and featuresList should be empty
+*/
+RUNNER_TEST(PrivilegeElementWrongFormat)
+{
+    ParserRunner parser;
+    WrtDB::ConfigParserData widgetConfig;
+
+    parser.Parse(miscWidgetsStuff + "configs/config_privilege6.xml",
+            ElementParserPtr(
+                new RootParser<WidgetParser>(widgetConfig,
+                    DPL::
+                    FromUTF32String(
+                        L"widget"))));
+
+    RUNNER_ASSERT(widgetConfig.privilegeList.empty());
+    RUNNER_ASSERT(widgetConfig.featuresList.empty());
+}
diff --git a/tests/general/PluginsInstallation.cpp b/tests/general/PluginsInstallation.cpp
new file mode 100644 (file)
index 0000000..8a779ea
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013 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    PluginsInstallation.cpp
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief   PluginsInstallation tests implementation
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <dpl/wrt-dao-ro/plugin_dao_read_only.h>
+#include <dpl/static_block.h>
+#include <installer_log.h>
+
+////////////////////////////////////////////////////////////////////////////////
+
+RUNNER_TEST_GROUP_INIT(PluginsInstallation)
+
+STATIC_BLOCK
+{
+    (void)system("wrt_reset_all.sh");
+    (void)system("wrt-installer -p");
+}
+
+#define MAKE_PLUGIN_CHECK_TESTCASE(TESTCASE, LIBNAME)                                                                                               \
+    RUNNER_TEST(PluginsInstallation_##TESTCASE)                                                                                                     \
+    {                                                                                                                                               \
+        Try {                                                                                                                                       \
+        WrtDB::PluginDAOReadOnly pdao(#LIBNAME);                                                                                                    \
+        RUNNER_ASSERT_MSG(pdao.getInstallationStatus() == WrtDB::PluginDAOReadOnly::INSTALLATION_COMPLETED, "Plugin is not installed correctly");   \
+        } Catch(DPL::Exception) {                                                                                                                   \
+            _E("%s", _rethrown_exception.DumpToString().c_str());                                                                                   \
+            RUNNER_ASSERT_MSG(false, "DPL::Exception");                                                                                             \
+        }                                                                                                                                           \
+    }                                                                                                                                               \
+
+MAKE_PLUGIN_CHECK_TESTCASE(contact, libwrt-plugins-tizen-contact.so)
+MAKE_PLUGIN_CHECK_TESTCASE(systemsetting, libwrt-plugins-tizen-systemsetting.so)
+MAKE_PLUGIN_CHECK_TESTCASE(systeminfo, libwrt-plugins-tizen-systeminfo.so)
+MAKE_PLUGIN_CHECK_TESTCASE(nfc, libwrt-plugins-tizen-nfc.so)
+MAKE_PLUGIN_CHECK_TESTCASE(content, libwrt-plugins-tizen-content.so)
+MAKE_PLUGIN_CHECK_TESTCASE(alarm, libwrt-plugins-tizen-alarm.so)
+MAKE_PLUGIN_CHECK_TESTCASE(power, libwrt-plugins-tizen-power.so)
+MAKE_PLUGIN_CHECK_TESTCASE(secureelement, libwrt-plugins-tizen-secureelement.so)
+MAKE_PLUGIN_CHECK_TESTCASE(timeutil, libwrt-plugins-tizen-timeutil.so)
+MAKE_PLUGIN_CHECK_TESTCASE(calendar, libwrt-plugins-tizen-calendar.so)
+MAKE_PLUGIN_CHECK_TESTCASE(datacontrol, libwrt-plugins-tizen-datacontrol.so)
+MAKE_PLUGIN_CHECK_TESTCASE(bookmark, libwrt-plugins-tizen-bookmark.so)
+MAKE_PLUGIN_CHECK_TESTCASE(messaging, libwrt-plugins-tizen-messaging.so)
+MAKE_PLUGIN_CHECK_TESTCASE(messageport, libwrt-plugins-tizen-messageport.so)
+MAKE_PLUGIN_CHECK_TESTCASE(datasync, libwrt-plugins-tizen-datasync.so)
+MAKE_PLUGIN_CHECK_TESTCASE(networkbearerselection, libwrt-plugins-tizen-networkbearerselection.so)
+MAKE_PLUGIN_CHECK_TESTCASE(package, libwrt-plugins-tizen-package.so)
+MAKE_PLUGIN_CHECK_TESTCASE(filesystem, libwrt-plugins-tizen-filesystem.so)
+MAKE_PLUGIN_CHECK_TESTCASE(download, libwrt-plugins-tizen-download.so)
+MAKE_PLUGIN_CHECK_TESTCASE(application, libwrt-plugins-tizen-application.so)
+MAKE_PLUGIN_CHECK_TESTCASE(notification, libwrt-plugins-tizen-notification.so)
+MAKE_PLUGIN_CHECK_TESTCASE(push, libwrt-plugins-tizen-push.so)
+MAKE_PLUGIN_CHECK_TESTCASE(tizen, libwrt-plugins-tizen-tizen.so)
+MAKE_PLUGIN_CHECK_TESTCASE(callhistory, libwrt-plugins-tizen-callhistory.so)
+MAKE_PLUGIN_CHECK_TESTCASE(bluetooth, libwrt-plugins-tizen-bluetooth.so)
diff --git a/tests/general/TaskConfigurationTests.cpp b/tests/general/TaskConfigurationTests.cpp
new file mode 100644 (file)
index 0000000..b129e10
--- /dev/null
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 2014 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    TaskConfigurationTests.cpp
+ * @author  Dominik Duda (d.duda@samsung.com)
+ * @version 1.0
+ * @brief   Tests functions from
+ * wrt-installer/src/jobs/widget_install/task_configuration.cpp
+ */
+#include <string>
+#include <installer_log.h>
+#include <InstallerWrapper.h>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/test/test_runner.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_installer_struct.h>
+#include <widget_install/task_configuration.h>
+#include <widget_install/job_widget_install.h>
+#include <installer_callbacks_translate.h>
+#include <pkg-manager/pkgmgr_signal_dummy.h>
+#include <memory>
+
+using namespace Jobs;
+using namespace WidgetInstall;
+
+RUNNER_TEST_GROUP_INIT(TaskConfiguration)
+
+namespace{
+const std::string wgtTmpPath = "/tmp/J7ZwBudste";
+const std::string wgtPath = InstallerWrapper::miscWidgetsStuff +
+        "widgets/widgetUpdateVer100Signed.wgt";
+const std::string tarCMD = "tar -xf " + InstallerWrapper::miscWidgetsStuff +
+                "widgets/widgetInDir.tar -C /tmp";
+
+std::string tizenId;
+
+void staticWrtInitPreloadStatusCallback(std::string tizenId, WrtErrStatus status,
+                                           void* userdata)
+{
+    return;
+}
+}
+
+/*
+Name: task_configuration_test_01
+Description: Installs widget which is needed for further tests.
+This installation will test standard use of the TaskConfiguration class.
+Expected: The widget should be successfully installed.
+*/
+RUNNER_TEST(task_configuration_test_01)
+{
+    //Install the widget to get a tizenID
+    InstallerWrapper::install(wgtPath, tizenId);
+
+    //Uninstall the widget in order to be sure that a next installation
+    //will be first.
+    RUNNER_ASSERT_MSG(InstallerWrapper::uninstall(tizenId),
+            "Failed to uninstall a widget");
+
+    //That will be the first installation of the widget.
+    RUNNER_ASSERT_MSG(
+            InstallerWrapper::install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed to install a widget");
+}
+
+/*
+Name: task_configuration_test_02
+Description: Tests recognizing an update installation.
+Expected: All task configration steps should be completed without errors.
+*/
+RUNNER_TEST(task_configuration_test_02)
+{
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.requestedPath = wgtPath;
+    i_context.job = new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    while(i < stepsCnt && result)
+    {
+        i++;
+        result = taskConf.NextStep();
+    }
+
+    RUNNER_ASSERT(i == stepsCnt);
+}
+
+/*
+Name: task_configuration_test_03
+Description: Tests widget installation with incorrect config.xml file.
+Expected: Task configuration process should throw an exception when parsing
+configuration file.
+*/
+RUNNER_TEST(task_configuration_test_03)
+{
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.requestedPath = InstallerWrapper::miscWidgetsStuff + "widgets/widgetFakeConfig.wgt";
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    Try{
+        while(i < stepsCnt && result)
+        {
+            i++;
+            result = taskConf.NextStep();
+        }
+    }
+    Catch(WidgetInstall::Exceptions::WidgetConfigFileInvalid){
+        RUNNER_ASSERT(i == 4);
+        return;
+    }
+
+    RUNNER_ASSERT_MSG(false,
+            "An Exception should be thrown if config.xml file is incorrect.");
+}
+
+/*
+Name: task_configuration_test_04
+Description: Tests task configuration for widget installation directly from
+a directory.
+Expected: Widget should be successfully installed.
+*/
+RUNNER_TEST(task_configuration_test_04)
+{
+    int ret = system(tarCMD.c_str());
+
+    RUNNER_ASSERT_MSG(!WIFEXITED(ret) || !WIFSIGNALED(ret),
+            "Cannot untar a widget to check direct installation from the directory!");
+
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.mode.extension = InstallMode::ExtensionType::DIR;
+    i_context.requestedPath = wgtTmpPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    while(i < stepsCnt && result)
+    {
+        i++;
+        result = taskConf.NextStep();
+    }
+
+    RUNNER_ASSERT(i == stepsCnt);
+}
+
+/*
+Name: task_configuration_test_05
+Description: Tests if an exception will ocure when there is no config.xml file
+in the widget directory.
+Expected: An exception should be thrown.
+*/
+RUNNER_TEST(task_configuration_test_05)
+{
+    int ret = system(tarCMD.c_str());
+
+    RUNNER_ASSERT_MSG(!WIFEXITED(ret) || !WIFSIGNALED(ret),
+            "Cannot untar widget to check direct installation from directory!");
+
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.mode.extension = InstallMode::ExtensionType::DIR;
+    i_context.requestedPath = wgtTmpPath + "/TestWgt.wgt";
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    Try{
+        while(i < stepsCnt && result)
+        {
+            i++;
+
+            if (i == 3)
+            {
+                //Remove config file
+                RUNNER_ASSERT(WrtUtilRemove(wgtTmpPath + "/config.xml"));
+            }
+
+            result = taskConf.NextStep();
+        }
+    }
+    Catch(WrtDB::WidgetDAOReadOnly::Exception::WidgetNotExist){
+        RUNNER_ASSERT(i == 3);
+        return;
+    }
+
+    RUNNER_ASSERT_MSG(false,
+            "An Exception should be thrown after deletion of config.xml file.");
+}
+
+/*
+Name: task_configuration_test_06
+Description: Tests if missing config file will be detected during parsing step.
+Expected: An exception should be thrown if there is no config file.
+*/
+RUNNER_TEST(task_configuration_test_06)
+{
+    int ret = system(tarCMD.c_str());
+
+    RUNNER_ASSERT_MSG(!WIFEXITED(ret) || !WIFSIGNALED(ret),
+            "Cannot untar widget to check direct installation from directory!");
+
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.mode.extension = InstallMode::ExtensionType::DIR;
+    i_context.requestedPath = wgtTmpPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    Try{
+        while(i < stepsCnt && result)
+        {
+            i++;
+
+            if (i == 4)
+            {
+                //Remove config file
+                RUNNER_ASSERT(WrtUtilRemove(wgtTmpPath + "/config.xml"));
+            }
+
+            result = taskConf.NextStep();
+        }
+    }
+    Catch(WidgetInstall::Exceptions::MissingConfig){
+        RUNNER_ASSERT(i == 4);
+        return;
+    }
+
+    RUNNER_ASSERT_MSG(false,
+            "An Exception should be thrown in parsing step if there is no "
+            "config.xml file in the directory.");
+}
+
+/*
+Name: task_configuration_test_07
+Description: Tests reinstallation of a widget from the directory.
+Expected: A widget should be successfully installed.
+*/
+RUNNER_TEST(task_configuration_test_07)
+{
+    int ret = system(tarCMD.c_str());
+
+    RUNNER_ASSERT_MSG(!WIFEXITED(ret) || !WIFSIGNALED(ret),
+            "Cannot untar widget to check direct installation from directory!");
+
+    //This widget is needed to be installed to find the tizen PkgId in the database
+    //during reinstallation step.
+    RUNNER_ASSERT_MSG(
+            InstallerWrapper::install(wgtTmpPath + "/TestWgt.wgt", tizenId) == InstallerWrapper::Success,
+            "Failed to install a widget");
+
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.mode.command = InstallMode::Command::REINSTALL;
+    i_context.mode.extension = InstallMode::ExtensionType::DIR;
+    i_context.requestedPath = wgtTmpPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    while(i < stepsCnt && result)
+    {
+        i++;
+        result = taskConf.NextStep();
+    }
+
+    RUNNER_ASSERT(i == stepsCnt);
+}
+
+/*
+Name: task_configuration_test_08
+Description: Tests recovery installation of the widget from the directory.
+Expected: A widget should be successfully installed.
+*/
+RUNNER_TEST(task_configuration_test_08)
+{
+    int ret = system(tarCMD.c_str());
+
+    RUNNER_ASSERT_MSG(!WIFEXITED(ret) || !WIFSIGNALED(ret),
+            "Cannot untar widget to check direct installation from directory!");
+
+    //This widget is needed to be installed to find the tizen PkgId in the database
+    //during reinstallation step.
+    RUNNER_ASSERT_MSG(
+            InstallerWrapper::install(wgtTmpPath + "/TestWgt.wgt", tizenId) == InstallerWrapper::Success,
+            "Failed to install a widget");
+
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.mode.command = InstallMode::Command::RECOVERY;
+    i_context.mode.extension = InstallMode::ExtensionType::DIR;
+    i_context.requestedPath = wgtTmpPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    while(i < stepsCnt && result)
+    {
+        i++;
+        result = taskConf.NextStep();
+    }
+
+    RUNNER_ASSERT(i == stepsCnt);
+}
+
+/*
+Name: task_configuration_test_09
+Description: Tests if a tizenAppID and tizenPkgID will be generated if were not
+set earlier.
+Expected: IDs should be properly generated.
+*/
+RUNNER_TEST(task_configuration_test_09)
+{
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.requestedPath = wgtPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    while(i < stepsCnt && result)
+    {
+        i++;
+
+        if (i == 5){
+            i_context.widgetConfig.tzAppid = L"";
+            i_context.widgetConfig.tzPkgid = L"";
+            i_context.widgetConfig.configInfo.tizenAppId = boost::none;
+            i_context.widgetConfig.configInfo.tizenPkgId = boost::none;
+        }
+
+        result = taskConf.NextStep();
+    }
+
+    RUNNER_ASSERT(i == stepsCnt &&
+            i_context.widgetConfig.tzAppid != L"" &&
+            i_context.widgetConfig.tzPkgid != L"");
+}
+
+/*
+Name: task_configuration_test_10
+Description: Tests if a tizenPkgID will be generated if was not set earlier.
+Expected: ID should be properly generated.
+*/
+RUNNER_TEST(task_configuration_test_10)
+{
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.requestedPath = wgtPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    while(i < stepsCnt && result)
+    {
+        i++;
+
+        if (i == 5){
+            i_context.widgetConfig.tzPkgid = L"";
+            i_context.widgetConfig.configInfo.tizenPkgId = boost::none;
+        }
+
+        result = taskConf.NextStep();
+    }
+
+    RUNNER_ASSERT(i == stepsCnt &&
+            i_context.widgetConfig.tzPkgid != L"");
+}
+
+/*
+Name: task_configuration_test_11
+Description: Tests if a tizenAppId and tizenPkgID will be generated if
+tizenApp ID is too short and tizenPkgID is not set.
+Expected: IDs should be properly generated. An exception should be thrown
+in step 9 beacuse this widget is already installed.
+*/
+RUNNER_TEST(task_configuration_test_11)
+{
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.requestedPath = wgtPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    Try{
+        while(i < stepsCnt && result)
+        {
+            i++;
+
+            if (i == 5){
+                i_context.widgetConfig.tzPkgid = L"";
+                i_context.widgetConfig.configInfo.tizenAppId = L"abcd";
+                i_context.widgetConfig.configInfo.tizenPkgId = boost::none;
+            }
+
+            result = taskConf.NextStep();
+        }
+    }
+    Catch(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid){
+        RUNNER_ASSERT(i == 9 &&
+                i_context.widgetConfig.tzPkgid != L"");
+        return;
+    }
+
+    RUNNER_ASSERT_MSG(false, "An exception should be thrown because this widget"
+            " is already installed!");
+}
+
+/*
+Name: task_configuration_test_12
+Description: Tests if a tizenAppId and tizenPkgID will be generated if
+tizenApp ID has incorrect characters and tizenPkgID is not set.
+Expected: IDs should be properly generated. An exception should be thrown
+in step 9 beacuse this widget is already installed.
+*/
+RUNNER_TEST(task_configuration_test_12)
+{
+    const WidgetInstallationStruct installerStruct(
+                    InstallerCallbacksTranslate::installFinishedCallback,
+                    InstallerCallbacksTranslate::installProgressCallback,
+                    new InstallerCallbacksTranslate::StatusCallbackStruct(
+                            NULL, &staticWrtInitPreloadStatusCallback, NULL),
+                    InstallMode(),
+                    std::make_shared<PackageManager::PkgmgrSignalDummy>());
+
+    InstallerContext i_context;
+
+    i_context.mode = InstallMode();
+    i_context.requestedPath = wgtPath;
+
+    i_context.job =
+            new Jobs::WidgetInstall::JobWidgetInstall(wgtPath, "",
+                    installerStruct);
+
+    TaskConfiguration taskConf(i_context);
+    size_t stepsCnt = taskConf.GetStepCount();
+
+    unsigned int i = 0;
+    bool result = true;
+
+    Try{
+        while(i < stepsCnt && result)
+        {
+            i++;
+
+            if (i == 5){
+                i_context.widgetConfig.tzPkgid = L"";
+                i_context.widgetConfig.configInfo.tizenAppId = L"1234!@#$qw";
+                i_context.widgetConfig.configInfo.tizenPkgId = boost::none;
+
+                FOREACH(localizedData, i_context.widgetConfig.configInfo.localizedDataSet)
+                {
+                    localizedData->second.name = L"1234!@#$qw";
+                }
+            }
+
+            result = taskConf.NextStep();
+        }
+    }
+    Catch(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid){
+        RUNNER_ASSERT(i == 9 &&
+                i_context.widgetConfig.tzPkgid != L"");
+        return;
+    }
+
+    RUNNER_ASSERT_MSG(false, "An exception should be thrown because this widget"
+            " is already installed!");
+}
diff --git a/tests/general/TestInit.cpp b/tests/general/TestInit.cpp
new file mode 100644 (file)
index 0000000..5c433ba
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012 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    TestInit.cpp
+ * @author  Tomasz Iwanek (t.iwanek@samsung.com)
+ * @version 1.0
+ * @brief   Main for wrt-installer general tests
+ */
+
+#include <dpl/test/test_runner.h>
+#include <installer_log.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
+#include <libxml/parser.h>
+
+int main (int argc, char *argv[])
+{
+    _D("Starting tests");
+
+    WrtDB::WrtDatabase::attachToThreadRW();
+    //libxml2 initialization
+    xmlInitParser();
+    LIBXML_TEST_VERSION
+
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+    xmlCleanupParser();
+    WrtDB::WrtDatabase::detachFromThread();
+
+    return status;
+}
diff --git a/tests/general/WidgetInstallManifestTests.cpp b/tests/general/WidgetInstallManifestTests.cpp
new file mode 100644 (file)
index 0000000..2a73cdd
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2013 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    WidgetInstallManifestTests.cpp
+ * @author  Dominik Duda (d.duda@samsung.com)
+ * @version 1.0
+ * @brief   Tests functions from wrt-installer/src/jobs/widget_install/manifest.cpp
+ */
+#include <string>
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/test/test_runner.h>
+#include <installer_log.h>
+#include <InstallerWrapper.h>
+#include <ManifestFile.h>
+#include <manifest.h>
+
+#include <iostream>
+
+using namespace Jobs;
+using namespace WidgetInstall;
+
+RUNNER_TEST_GROUP_INIT(WidgetInstallManifest)
+
+namespace{
+    const std::string manifestFilePath("/tmp/manifest.xml");
+    Manifest manifest;
+}
+
+/*
+Name: wgt_install_manifest_test_01
+Description: Tests creation of an empty manifest file.
+Expected: The file should be created.
+*/
+RUNNER_TEST(wgt_install_manifest_test_01)
+{
+    Manifest manifest;
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    RUNNER_ASSERT(WrtUtilFileExists(manifestFilePath));
+}
+
+/*
+Name: wgt_install_manifest_test_02
+Description: Tests creation of a manifest file with empty icon, label, author
+and description nodes.
+Expected: All nodes should be successfully created.
+*/
+RUNNER_TEST(wgt_install_manifest_test_02)
+{
+    Manifest manifest;
+
+    manifest.addIcon(IconType());
+    manifest.addLabel(LabelType());
+    manifest.addAuthor(AuthorType());
+    manifest.addDescription(DescriptionType());
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile mFile(manifestFilePath);
+
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:icon") == "");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:label") == "");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:author") == "");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:description") == "");
+}
+
+/*
+Name: wgt_install_manifest_test_03
+Description: Tests creation of a manifest file with icon, label, author and
+description nodes.
+Expected: All nodes should be successfully created.
+*/
+RUNNER_TEST(wgt_install_manifest_test_03)
+{
+    Manifest manifest;
+
+    manifest.addIcon(IconType(L"manifestIcon.png"));
+    manifest.addLabel(LabelType(L"manifest label"));
+    manifest.addDescription(DescriptionType(L"manifest description"));
+    manifest.addDescription(DescriptionType(L"opis manifestu", L"pl-pl"));
+    manifest.addAuthor(AuthorType(
+            DPL::String(L"some@email.com"),
+            DPL::String(L"emailto:some@email.com"),
+            DPL::String(L"en"),
+            DPL::String(L"Manifest email")));
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile mFile(manifestFilePath);
+
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:icon")
+            == "manifestIcon.png");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:label")
+            == "manifest label");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:author/@email")
+            == "some@email.com");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:author/@href")
+            == "emailto:some@email.com");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:author/@xml:lang")
+            == "en");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:author")
+            == "Manifest email");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:description[1]")
+            == "manifest description");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:description[2]")
+            == "opis manifestu");
+    RUNNER_ASSERT(mFile.getValueByXpath("/p:manifest/p:description[2]/@xml:lang")
+            == "pl-pl");
+}
+
+/*
+Name: wgt_install_manifest_test_04
+Description: Tests creation of an account node with a capability node as a child
+node of the account-provider node.
+Expected: The node should be successfully created with all attributes and child
+nodes.
+*/
+RUNNER_TEST(wgt_install_manifest_test_04)
+{
+    Manifest manifest;
+    Account acc;
+    AccountProviderType accProv;
+    std::pair<DPL::String, DPL::String> icon;
+
+    accProv.appid = L"id.manifest.xml";
+    accProv.multiAccount = L"true";
+
+    accProv.name.push_back(LabelType());
+    accProv.name.push_back(LabelType(L"only name"));
+    accProv.name.push_back(LabelType(L"name with lang", L"en-gb"));
+    accProv.name.push_back(LabelType(L"nazwa z lang", L"pl-pl"));
+
+    accProv.capability.push_back(L"Capability_01");
+    accProv.capability.push_back(L"");
+
+    icon.first = L"account";
+    icon.second = L"/tmp/icon.png";
+    accProv.icon.push_back(icon);
+
+    acc.addAccountProvider(accProv);
+
+    manifest.addAccount(acc);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/@appid") == "id.manifest.xml");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/@multiple-accounts-support") == "true");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:icon/@section") == "account");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:icon") == "/tmp/icon.png");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[1]") == "");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[2]") == "only name");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[3]") == "name with lang");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[4]") == "name with lang");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[4]/@xml:lang") == "en-gb");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[5]") == "nazwa z lang");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:label[5]/@xml:lang") == "pl-pl");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:capability[1]") == "Capability_01");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:account/"
+            "p:account-provider/p:capability[2]") == "");
+}
+
+/*
+Name: wgt_install_manifest_test_05
+Description: Tests creation of a service-application node.
+Expected: The node should be successfully created with all attributes and child
+nodes.
+*/
+RUNNER_TEST(wgt_install_manifest_test_05)
+{
+    Manifest manifest;
+    AppControlType appType;
+    ServiceApplicationType servApp;
+
+    appType.addMime(L"text/plain");
+    appType.addUri(L"http://someurl.org");
+    appType.addOperation(L"simple operation");
+
+    servApp.setAppid(L"manifest.id");
+    servApp.setAutoRestart(false);
+    servApp.setExec(L"exec");
+    servApp.setOnBoot(false);
+    servApp.setType(L"someType");
+    servApp.addLabel(LabelType(L"simpleLabel"));
+    servApp.addIcon(IconType(L"simpleIcon.png"));
+    servApp.addAppControl(appType);
+
+    manifest.addServiceApplication(servApp);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/@appid") == "manifest.id");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/@auto-restart") == "false");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/@exec") == "exec");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/@on-boot") == "false");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/@type") == "someType");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/p:label") == "simpleLabel");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/p:icon") == "simpleIcon.png");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/p:app-control/p:operation/@name") == "simple operation");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/p:app-control/p:uri/@name") == "http://someurl.org");
+    RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:service-application/p:app-control/p:mime/@name") == "text/plain");
+}
+
+/*
+Name: wgt_install_manifest_test_06
+Description: Creats manifest file with an empty ui-application node.
+Expected: The empty ui-application node should be created. All node's parameters
+should be empty too.
+*/
+RUNNER_TEST(wgt_install_manifest_test_06)
+{
+    Manifest manifest;
+    UiApplicationType uiApp;
+
+    manifest.addUiApplication(uiApp);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    Try
+    {
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application") == "");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@appid") == "");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@exec") == "");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@type") == "");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@extraid") == "");
+    }
+    Catch(ManifestFile::ManifestParseError)
+    {
+        RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+    }
+}
+
+/*
+Name: wgt_install_manifest_test_07
+Description: Tests creation of an ui-application node.
+Expected: The node should be successfully created with all attributes and child
+nodes.
+*/
+RUNNER_TEST(wgt_install_manifest_test_07)
+{
+    Manifest manifest;
+    UiApplicationType uiApp;
+
+    uiApp.setAppid(L"manifest.AppID");
+    uiApp.setCategories(L"categories");
+    uiApp.setExtraid(L"extraID");
+    uiApp.setExec(L"exec");
+    uiApp.setMultiple(false);
+    uiApp.setNodisplay(false);
+    uiApp.setTaskmanage(true);
+    uiApp.setType(L"uiType");
+
+    uiApp.addLabel(LabelType(L"uiLabel"));
+    uiApp.addIcon(IconType(L"icon.png"));
+    uiApp.addAppCategory(L"appCategory");
+    uiApp.addMetadata(MetadataType(DPL::OptionalString(L"key"), DPL::OptionalString(L"value")));
+
+    AppControlType appCtrl;
+    appCtrl.addMime(L"text/plain");
+    appCtrl.addOperation(L"appOperation");
+    appCtrl.addUri(L"some.uri.com");
+
+    uiApp.addAppControl(appCtrl);
+
+    manifest.addUiApplication(uiApp);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    Try
+    {
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@appid") == "manifest.AppID");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@exec") == "exec");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@type") == "uiType");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@extraid") == "extraID");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@multiple") == "false");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@nodisplay") == "false");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@taskmanage") == "true");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/@categories") == "categories");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:label") == "uiLabel");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:icon") == "icon.png");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:category/@name") == "appCategory");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:metadata/@key") == "key");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:metadata/@value") == "value");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:app-control/p:operation/@name") == "appOperation");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:app-control/p:uri/@name") == "some.uri.com");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ui-application/p:app-control/p:mime/@name") == "text/plain");
+    }
+    Catch(ManifestFile::ManifestParseError)
+    {
+        RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+    }
+}
+
+/*
+Name: wgt_install_manifest_test_08
+Description: Tests creation of an ime-application node.
+Expected: The node should be successfully created with all attributes and child
+nodes.
+*/
+RUNNER_TEST(wgt_install_manifest_test_08)
+{
+    Manifest manifest;
+    ImeApplicationType ime;
+
+    ime.setAppid(L"appID");
+    ime.setExec(L"exec");
+    ime.setMultiple(true);
+    ime.setNodisplay(true);
+    ime.setType(L"type");
+    ime.addIcon(IconType(L"imeicon.png"));
+    ime.addLabel(LabelType(L"imeLabel"));
+
+    manifest.addImeApplication(ime);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    Try
+    {
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/@appid") == "appID");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/@exec") == "exec");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/@multiple") == "true");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/@nodisplay") == "true");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/@type") == "type");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/p:label") == "imeLabel");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:ime-application/p:icon") == "imeicon.png");
+    }
+    Catch(ManifestFile::ManifestParseError)
+    {
+        RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+    }
+}
+
+/*
+Name: wgt_install_manifest_test_09
+Description: Tests creation of a livebox node.
+Expected: The node should be successfully created with all child nodes.
+*/
+RUNNER_TEST(wgt_install_manifest_test_09)
+{
+    Manifest manifest;
+    LiveBoxInfo lbox;
+    BoxInfoType binfo;
+    BoxSizeType bst;
+    BoxLabelType blt;
+    WrtDB::ConfigParserData::LiveboxInfo::BoxSizeInfo bsize;
+
+    lbox.setLiveboxId(L"lboxID");
+    lbox.setIcon(L"lboxicon.png");
+    lbox.setPrimary(L"lboxprim");
+
+
+    blt.push_back(std::pair<DPL::String,DPL::String>(L"pl-pl", L"lbl"));
+    lbox.setLabel(blt);
+
+    bsize.m_preview = L"true";
+    bsize.m_size = L"20;20";
+    bsize.m_useDecoration = L"false";
+    bst.push_back(bsize);
+
+    binfo.boxMouseEvent = L"onclick";
+    binfo.boxSize = bst;
+    binfo.boxSrc = L"boxSrc";
+    binfo.boxTouchEffect = L"false";
+    binfo.pdHeight = L"100";
+    binfo.pdSrc = L"pdSrc";
+    binfo.pdWidth = L"100";
+    lbox.setBox(binfo);
+
+    manifest.addLivebox(lbox);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    Try
+    {
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/@appid") == "lboxID");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/@primary") == "lboxprim");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/@abi") == "html");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/@network") == "true");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/@nodisplay") == "false");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:label[1]") == "lbl");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:label[1]/@xml:lang") == "pl-pl");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:label[2]") == "NO NAME");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:icon") == "lboxicon.png");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/@type") == "buffer");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/@mouse_event") == "onclick");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/@touch_effect") == "false");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/p:size") == "20;20");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/p:size/@preview") == "true");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/p:size/@need_frame") == "false");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:box/p:script/@src") == "boxSrc");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:pd/@type") == "buffer");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:pd/p:size") == "100x100");
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:livebox/p:pd/p:script/@src") == "pdSrc");
+    }
+    Catch(ManifestFile::ManifestParseError)
+    {
+        RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+    }
+}
+
+/*
+Name: wgt_install_manifest_test_10
+Description: Tests creation of a privilege node.
+Expected: The node should be successfully created.
+*/
+RUNNER_TEST(wgt_install_manifest_test_10)
+{
+    PrivilegeType prv1;
+
+    prv1.addPrivilegeName(L"name_1");
+
+    manifest.addPrivileges(prv1);
+    manifest.generate(DPL::FromASCIIString(manifestFilePath));
+
+    ManifestFile manReader(manifestFilePath);
+
+    Try
+    {
+        RUNNER_ASSERT(manReader.getValueByXpath("/p:manifest/p:privileges/p:privilege") == "name_1");
+    }
+    Catch(ManifestFile::ManifestParseError)
+    {
+        RUNNER_ASSERT_MSG(false,DPL::Exception::KnownExceptionToString(_rethrown_exception));
+    }
+}
+
+/*
+Name: wgt_install_manifest_test_11
+Description: Deletes the XML file used for tests.
+Expected: The file should be successfully deleted.
+*/
+RUNNER_TEST(wgt_install_manifest_test_11)
+{
+    RUNNER_ASSERT(WrtUtilRemove(manifestFilePath));
+}
diff --git a/tests/general/WidgetLocationTests.cpp b/tests/general/WidgetLocationTests.cpp
new file mode 100644 (file)
index 0000000..f7075de
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2013 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    WidgetLocationTests.cpp
+ * @author  Maciej Piotrowski (m.piotrowski@samsung.com)
+ * @version 1.0
+ * @brief   WidgetLocation tests
+ */
+
+#include <dpl/test/test_runner.h>
+#include <dpl/utils/wrt_utility.h>
+#include <widget_location.h>
+
+RUNNER_TEST_GROUP_INIT(WidgetLocation)
+
+
+/*
+Name: WidgetLocationCleanInit
+Description: Tests WidgetLocation creation for WidgetLocation::WidgetLocation
+*/
+RUNNER_TEST(WidgetLocationCleanInit)
+{
+    WidgetLocation wl;
+
+    RUNNER_ASSERT(wl.getInstallationDir() == "");
+    RUNNER_ASSERT(wl.getPackageInstallationDir() == "/");
+    RUNNER_ASSERT(wl.getSourceDir() == "//res/wgt");
+    RUNNER_ASSERT(wl.getBinaryDir() == "//bin");
+    RUNNER_ASSERT(wl.getUserBinaryDir() == "/opt/usr/apps///bin");
+    RUNNER_ASSERT(wl.getExecFile() == "//bin/");
+    RUNNER_ASSERT(wl.getBackupDir() == "/.backup");
+    RUNNER_ASSERT(wl.getBackupSourceDir() == "/.backup/res/wgt");
+    RUNNER_ASSERT(wl.getBackupBinaryDir() == "/.backup/bin");
+    RUNNER_ASSERT(wl.getBackupExecFile() == "/.backup/bin/");
+    RUNNER_ASSERT(wl.getBackupPrivateDir() == "/.backup/data");
+    RUNNER_ASSERT(wl.getUserDataRootDir() == "/opt/usr/apps/");
+    RUNNER_ASSERT(wl.getPrivateStorageDir() == "/opt/usr/apps//data");
+    RUNNER_ASSERT(wl.getPrivateTempStorageDir() == "/opt/usr/apps//tmp");
+    RUNNER_ASSERT(wl.getSharedRootDir() == "/opt/usr/apps//shared");
+    RUNNER_ASSERT(wl.getSharedResourceDir() == "/opt/usr/apps//shared/res");
+    RUNNER_ASSERT(wl.getSharedDataDir() == "/opt/usr/apps//shared/data");
+    RUNNER_ASSERT(wl.getSharedTrustedDir() == "/opt/usr/apps//shared/trusted");
+    RUNNER_ASSERT(wl.getBackupSharedDir() == "/.backup/shared");
+    RUNNER_ASSERT(wl.getBackupSharedDataDir() == "/.backup/shared/data");
+    RUNNER_ASSERT(wl.getBackupSharedTrustedDir() == "/.backup/shared/trusted");
+    RUNNER_ASSERT(wl.getNPPluginsDir() == "//res/wgt/plugins");
+    RUNNER_ASSERT(wl.getNPPluginsExecFile() == "//bin/.npruntime");
+    RUNNER_ASSERT(WrtUtilDirExists(wl.getTemporaryPackageDir()));
+    RUNNER_ASSERT(wl.getTemporaryRootDir() == "//res/wgt");
+    RUNNER_ASSERT(wl.getInstalledIconPath() == "");
+    RUNNER_ASSERT(wl.getWidgetSource() == "");
+    RUNNER_ASSERT(wl.getPkgId() == DPL::String(L""));
+}
+
+/*
+Name: WidgetLocationPkgIdInit
+Description: Tests WidgetLocation creation for WidgetLocation::WidgetLocation wirh pkgid
+*/
+RUNNER_TEST(WidgetLocationPkgIdInit)
+{
+    WidgetLocation wl("1234567890");
+
+    RUNNER_ASSERT(wl.getInstallationDir() == "");
+    RUNNER_ASSERT(wl.getPackageInstallationDir() == "/1234567890");
+    RUNNER_ASSERT(wl.getSourceDir() == "/1234567890/res/wgt");
+    RUNNER_ASSERT(wl.getBinaryDir() == "/1234567890/bin");
+    RUNNER_ASSERT(wl.getUserBinaryDir() == "/opt/usr/apps/1234567890//bin");
+    RUNNER_ASSERT(wl.getExecFile() == "/1234567890/bin/");
+    RUNNER_ASSERT(wl.getBackupDir() == "/1234567890.backup");
+    RUNNER_ASSERT(wl.getBackupSourceDir() == "/1234567890.backup/res/wgt");
+    RUNNER_ASSERT(wl.getBackupBinaryDir() == "/1234567890.backup/bin");
+    RUNNER_ASSERT(wl.getBackupExecFile() == "/1234567890.backup/bin/");
+    RUNNER_ASSERT(wl.getBackupPrivateDir() == "/1234567890.backup/data");
+    RUNNER_ASSERT(wl.getUserDataRootDir() == "/opt/usr/apps/1234567890");
+    RUNNER_ASSERT(wl.getPrivateStorageDir() == "/opt/usr/apps/1234567890/data");
+    RUNNER_ASSERT(wl.getPrivateTempStorageDir() == "/opt/usr/apps/1234567890/tmp");
+    RUNNER_ASSERT(wl.getSharedRootDir() == "/opt/usr/apps/1234567890/shared");
+    RUNNER_ASSERT(wl.getSharedResourceDir() == "/opt/usr/apps/1234567890/shared/res");
+    RUNNER_ASSERT(wl.getSharedDataDir() == "/opt/usr/apps/1234567890/shared/data");
+    RUNNER_ASSERT(wl.getSharedTrustedDir() == "/opt/usr/apps/1234567890/shared/trusted");
+    RUNNER_ASSERT(wl.getBackupSharedDir() == "/1234567890.backup/shared");
+    RUNNER_ASSERT(wl.getBackupSharedDataDir() == "/1234567890.backup/shared/data");
+    RUNNER_ASSERT(wl.getBackupSharedTrustedDir() == "/1234567890.backup/shared/trusted");
+    RUNNER_ASSERT(wl.getNPPluginsDir() == "/1234567890/res/wgt/plugins");
+    RUNNER_ASSERT(wl.getNPPluginsExecFile() == "/1234567890/bin/.npruntime");
+    RUNNER_ASSERT(WrtUtilDirExists(wl.getTemporaryPackageDir()));
+    RUNNER_ASSERT(wl.getTemporaryRootDir() == "/1234567890/res/wgt");
+    RUNNER_ASSERT(wl.getInstalledIconPath() == "");
+    RUNNER_ASSERT(wl.getWidgetSource() == "");
+    RUNNER_ASSERT(wl.getPkgId() == DPL::String(L"1234567890"));
+}
+
+/*
+Name: WidgetLocationPkgIdInitAppId
+Description: Tests WidgetLocation creation for WidgetLocation::WidgetLocation
+             with pkgid and appid
+*/
+RUNNER_TEST(WidgetLocationPkgIdInitAppId)
+{
+    WidgetLocation wl("1234567890");
+    wl.registerAppid("id123456");
+
+    RUNNER_ASSERT(wl.getInstallationDir() == "");
+    RUNNER_ASSERT(wl.getPackageInstallationDir() == "/1234567890");
+    RUNNER_ASSERT(wl.getSourceDir() == "/1234567890/res/wgt");
+    RUNNER_ASSERT(wl.getBinaryDir() == "/1234567890/bin");
+    RUNNER_ASSERT(wl.getUserBinaryDir() == "/opt/usr/apps/1234567890//bin");
+    RUNNER_ASSERT(wl.getExecFile() == "/1234567890/bin/id123456");
+    RUNNER_ASSERT(wl.getBackupDir() == "/1234567890.backup");
+    RUNNER_ASSERT(wl.getBackupSourceDir() == "/1234567890.backup/res/wgt");
+    RUNNER_ASSERT(wl.getBackupBinaryDir() == "/1234567890.backup/bin");
+    RUNNER_ASSERT(wl.getBackupExecFile() == "/1234567890.backup/bin/id123456");
+    RUNNER_ASSERT(wl.getBackupPrivateDir() == "/1234567890.backup/data");
+    RUNNER_ASSERT(wl.getUserDataRootDir() == "/opt/usr/apps/1234567890");
+    RUNNER_ASSERT(wl.getPrivateStorageDir() == "/opt/usr/apps/1234567890/data");
+    RUNNER_ASSERT(wl.getPrivateTempStorageDir() == "/opt/usr/apps/1234567890/tmp");
+    RUNNER_ASSERT(wl.getSharedRootDir() == "/opt/usr/apps/1234567890/shared");
+    RUNNER_ASSERT(wl.getSharedResourceDir() == "/opt/usr/apps/1234567890/shared/res");
+    RUNNER_ASSERT(wl.getSharedDataDir() == "/opt/usr/apps/1234567890/shared/data");
+    RUNNER_ASSERT(wl.getSharedTrustedDir() == "/opt/usr/apps/1234567890/shared/trusted");
+    RUNNER_ASSERT(wl.getBackupSharedDir() == "/1234567890.backup/shared");
+    RUNNER_ASSERT(wl.getBackupSharedDataDir() == "/1234567890.backup/shared/data");
+    RUNNER_ASSERT(wl.getBackupSharedTrustedDir() == "/1234567890.backup/shared/trusted");
+    RUNNER_ASSERT(wl.getNPPluginsDir() == "/1234567890/res/wgt/plugins");
+    RUNNER_ASSERT(wl.getNPPluginsExecFile() == "/1234567890/bin/id123456.npruntime");
+    RUNNER_ASSERT(WrtUtilDirExists(wl.getTemporaryPackageDir()));
+    RUNNER_ASSERT(wl.getTemporaryRootDir() == "/1234567890/res/wgt");
+    RUNNER_ASSERT(wl.getWidgetSource() == "");
+    RUNNER_ASSERT(wl.getPkgId() == DPL::String(L"1234567890"));
+}
+
+/*
+Name: WidgetLocationExternalLocations
+Description: Tests WidgetLocation::listExternalLocations() and WidgetLocation::registerExternalLocation()
+*/
+RUNNER_TEST(WidgetLocationExternalLocations)
+{
+    WidgetLocation wl;
+    RUNNER_ASSERT(wl.listExternalLocations().size() == 0);
+    wl.registerExternalLocation("filepath1");
+    wl.registerExternalLocation("filepath2");
+    wl.registerExternalLocation("filepath3");
+    RUNNER_ASSERT(wl.listExternalLocations().size() == 3);
+    wl.registerExternalLocation("filepath1");
+    RUNNER_ASSERT(wl.listExternalLocations().size() == 4);
+}
+
+/*
+Name: WidgetLocationAdvancedInit1
+Description: Tests WidgetLocation::WidgetLocation()
+*/
+RUNNER_TEST(WidgetLocationAdvancedInit1)
+{
+    WidgetLocation wl("9876543210", "/opt/usr/apps/9876543210", WrtDB::PKG_TYPE_NOMAL_WEB_APP, false, InstallMode::ExtensionType::DIR);
+    RUNNER_ASSERT(WrtUtilDirExists(wl.getTemporaryPackageDir()));
+    RUNNER_ASSERT(wl.getTemporaryRootDir() == "/opt/usr/apps/9876543210/res/wgt");
+}
+
+
+/*
+Name: WidgetLocationAdvancedInit2
+Description: Tests WidgetLocation::WidgetLocation()
+*/
+RUNNER_TEST(WidgetLocationAdvancedInit2)
+{
+    WidgetLocation wl("1234567890", "/opt/usr/apps/1234567890/", "/tmp/tempdir/", WrtDB::PKG_TYPE_NOMAL_WEB_APP, false, InstallMode::ExtensionType::WGT);
+    RUNNER_ASSERT(wl.getTemporaryPackageDir() == "/tmp/tempdir/");
+    RUNNER_ASSERT(wl.getTemporaryRootDir() == "/opt/usr/apps/1234567890/res/wgt");
+    //fails because there is no use of Jobs::WidgetInstall::createTempPath like it is in constructor
+    //from WidgetLocationAdvancedInit1 case
+    //RUNNER_ASSERT(WrtUtilDirExists(wl.getTemporaryPackageDir()));
+}
diff --git a/tests/general/WidgetUpdateTests.cpp b/tests/general/WidgetUpdateTests.cpp
new file mode 100644 (file)
index 0000000..064e545
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2013 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    WidgetUpdateTests.cpp
+ * @author  Grzegorz Rynkowski (g.rynkowski@samsung.com)
+ * @version 1.0
+ * @brief   Test a process of updating web applications.
+ */
+
+#include <string>
+#include <dpl/test/test_runner.h>
+#include <InstallerWrapper.h>
+#include <fstream>
+
+using namespace InstallerWrapper;
+
+#define RUNNER_ASSERT_MSG_SAFE(test, message)                                  \
+    {                                                                          \
+        DPL::Test::TestRunnerSingleton::Instance().MarkAssertion();            \
+                                                                               \
+        if (!(test))                                                           \
+        {                                                                      \
+            uninstall(tizenId);                                                \
+            std::ostringstream assertMsg;                                      \
+            assertMsg << message;                                              \
+            throw DPL::Test::TestRunner::TestFailed(#test,                     \
+                                                    __FILE__,                  \
+                                                    __LINE__,                  \
+                                                    assertMsg.str());          \
+        }                                                                      \
+    }
+
+RUNNER_TEST_GROUP_INIT(WidgetUpdate)
+
+/*
+Name: validUpdateOfSigned
+Description: Tests update the web app where origin and a new one are signed.
+Expected: Widget should be successfully installed.
+*/
+RUNNER_TEST(validUpdateOfSigned)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+    RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed to install widget");
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+    RUNNER_ASSERT_MSG_SAFE(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed update in case both programs are signed");
+    uninstall(tizenId);
+}
+
+/*
+Name: validUpdateOfUnsigned
+Description: Tests update the web app where origin and a new one are unsigned.
+Expected: Widget should be successfully updated.
+*/
+RUNNER_TEST(validUpdateOfUnsigned)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt";
+    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+            "Failed to install widget");
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt";
+    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success == install(wgtPath, tizenId),
+                "Failed update in case both programs are signed");
+    uninstall(tizenId);
+}
+
+/*
+ * Information:
+ * These tests are incompatible to the specification 2.1
+ *      (but compatible to the specification 3.0).
+ */
+///*
+//Name: unupdateOfSigned
+//Description: Tests update that signed web app could be downgraded.
+//Expected: Widget should not be updated.
+//*/
+//RUNNER_TEST(unupdateOfSigned)
+//{
+//    std::string tizenId;
+//    std::string wgtPath;
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+//    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+//            "Failed to install widget");
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+//    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+//            "Unupdate should be prohibited.");
+//    uninstall(tizenId);
+//}
+//
+///*
+//Name: unupdateOfSigned
+//Description: Tests update that unsigned web app could be downgraded.
+//Expected: Widget should not be updated.
+//*/
+//RUNNER_TEST(unupdateOfUnsigned)
+//{
+//    std::string tizenId;
+//    std::string wgtPath;
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt";
+//    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+//            "Failed to install widget");
+//
+//    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt";
+//    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+//            "Unupdate should be prohibited.");
+//    uninstall(tizenId);
+//}
+
+/*
+Name: validUpdateOfCrossSigned
+Description: Tests update the web app where one of widgets are signed and second not.
+Expected: Widget should not be updated.
+*/
+RUNNER_TEST(updateOfCrossSignedWidgets)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    {
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt";
+        RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+                "Failed to install widget");
+
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+        RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+                "The update unsigned app by the signed app should not be possible");
+        uninstall(tizenId);
+    }
+    {
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+        RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+                "Failed to install widget");
+
+        wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt";
+        RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+                "The update signed app by the unsigned app should not be possible");
+        uninstall(tizenId);
+    }
+}
+
+
+/*
+Name: updateAnotherAuthor
+Description: Tests update the web app by the widget signed by another author.
+Expected: Widget should not be updated.
+*/
+RUNNER_TEST(updateAnotherAuthor)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+    RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId),
+            "Failed to install widget");
+
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220SignedAnotherAuthor.wgt";
+    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId),
+            "The update by another author should not be possible");
+    uninstall(tizenId);
+}
+
+
+/*
+Name: updateWidgetDataRemember
+Description: Tests of keeping app data during widget updating.
+Expected: App data should be kept.
+*/
+RUNNER_TEST(updateWidgetDataRemember)
+{
+    std::string tizenId;
+    std::string wgtPath;
+
+    // Installation of the widget
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt";
+    RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success,
+            "Failed to install widget");
+
+    // Creating a file
+    std::string filePath = "/opt/usr/apps/HAdisUJ4Kn/data/test";
+    std::string text = "slonce swieci dzisiaj wyjatkowo wysoko";
+    std::string command = "echo " + text + " > " + filePath;
+    system(command.c_str());
+
+    // Second installation of the widget
+    wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt";
+    RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success == install(wgtPath, tizenId),
+            "Failed update in case both programs are signed");
+
+
+    // Checking of the file created before
+    std::stringstream ss;
+    std::ifstream file(filePath);
+    RUNNER_ASSERT_MSG_SAFE(file.good(), "File is gone");
+
+    for( std::string line; getline( file, line ); ss << line);
+    file.close();
+    RUNNER_ASSERT_MSG_SAFE(text == ss.str(), "Content of file is not the same");
+    uninstall(tizenId);
+}
diff --git a/tests/general/configs/AllowNavigationEmpty.xml b/tests/general/configs/AllowNavigationEmpty.xml
new file mode 100644 (file)
index 0000000..720795c
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:allow-navigation/>
+  <tizen:allow-navigation>test2.org test3.org</tizen:allow-navigation>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AllowNavigationMultipleHosts.xml b/tests/general/configs/AllowNavigationMultipleHosts.xml
new file mode 100644 (file)
index 0000000..4663bb1
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:allow-navigation>http://test2.org test3.org *.test4.org *</tizen:allow-navigation>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AllowNavigationMultipleHostsMultiline.xml b/tests/general/configs/AllowNavigationMultipleHostsMultiline.xml
new file mode 100644 (file)
index 0000000..d3128c4
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:allow-navigation>
+       http://test2.org    
+       *.test4.org     *
+                               
+               test3.org           
+  </tizen:allow-navigation>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetAutoLaunchEmpty.xml b/tests/general/configs/AppWidgetAutoLaunchEmpty.xml
new file mode 100644 (file)
index 0000000..5830a27
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true" auto-launch="">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetAutoLaunchWrongValue.xml b/tests/general/configs/AppWidgetAutoLaunchWrongValue.xml
new file mode 100644 (file)
index 0000000..b510ebb
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true" auto-launch="dummy">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetFull.xml b/tests/general/configs/AppWidgetFull.xml
new file mode 100644 (file)
index 0000000..eaa2a0a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true" update-period="1800.0" auto-launch="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-icon src="box-icon.png"/>
+    <tizen:box-content src="app-widget/index.html" mouse-event="true" touch-effect="false">
+        <tizen:box-size preview="app-widget/preview-lb1-11.png" use-decoration="false">1x1</tizen:box-size>
+        <tizen:pd src="pd/index.html" width="720" height="150" />
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
\ No newline at end of file
diff --git a/tests/general/configs/AppWidgetIdEmpty.xml b/tests/general/configs/AppWidgetIdEmpty.xml
new file mode 100644 (file)
index 0000000..ae70c36
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetIdTooLong.xml b/tests/general/configs/AppWidgetIdTooLong.xml
new file mode 100644 (file)
index 0000000..eb0066e
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmg34.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetIdTooShort.xml b/tests/general/configs/AppWidgetIdTooShort.xml
new file mode 100644 (file)
index 0000000..80a5ed2
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmg.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetIdWrongChar.xml b/tests/general/configs/AppWidgetIdWrongChar.xml
new file mode 100644 (file)
index 0000000..f132c0f
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="ti$enScmg3.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetMinimal.xml b/tests/general/configs/AppWidgetMinimal.xml
new file mode 100644 (file)
index 0000000..aa7bb26
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetMultipleBoxContent.xml b/tests/general/configs/AppWidgetMultipleBoxContent.xml
new file mode 100644 (file)
index 0000000..619c225
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+    <tizen:box-content src="app-widget/index2.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetMultipleBoxIcon.xml b/tests/general/configs/AppWidgetMultipleBoxIcon.xml
new file mode 100644 (file)
index 0000000..9b905bf
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-icon src=“box-icon1.png"/>
+    <tizen:box-icon src=“box-icon2.png"/>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetMultipleBoxLabel.xml b/tests/general/configs/AppWidgetMultipleBoxLabel.xml
new file mode 100644 (file)
index 0000000..c046194
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>test</tizen:box-label>
+    <tizen:box-label xml:lang="en">test_en</tizen:box-label>
+    <tizen:box-label xml:lang="pl">test_pl</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetMultiplePrimary.xml b/tests/general/configs/AppWidgetMultiplePrimary.xml
new file mode 100644 (file)
index 0000000..365fc19
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+   <tizen:app-widget id="tizenScmgz.Sample.default" primary="false">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetNoBoxContent.xml b/tests/general/configs/AppWidgetNoBoxContent.xml
new file mode 100644 (file)
index 0000000..8d882f5
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetNoBoxLabel.xml b/tests/general/configs/AppWidgetNoBoxLabel.xml
new file mode 100644 (file)
index 0000000..8289b97
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetNoId.xml b/tests/general/configs/AppWidgetNoId.xml
new file mode 100644 (file)
index 0000000..39b0a32
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetNoPrimary.xml b/tests/general/configs/AppWidgetNoPrimary.xml
new file mode 100644 (file)
index 0000000..f501865
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetPrimaryEmpty.xml b/tests/general/configs/AppWidgetPrimaryEmpty.xml
new file mode 100644 (file)
index 0000000..acb58ff
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetPrimaryWrongValue.xml b/tests/general/configs/AppWidgetPrimaryWrongValue.xml
new file mode 100644 (file)
index 0000000..bcb4cdf
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="dummy">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetUpdatePeriodEmpty.xml b/tests/general/configs/AppWidgetUpdatePeriodEmpty.xml
new file mode 100644 (file)
index 0000000..2f41ddb
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true" update-period="">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetUpdatePeriodLow.xml b/tests/general/configs/AppWidgetUpdatePeriodLow.xml
new file mode 100644 (file)
index 0000000..4c54ab8
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true" update-period="18">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/AppWidgetUpdatePeriodWrongFormat.xml b/tests/general/configs/AppWidgetUpdatePeriodWrongFormat.xml
new file mode 100644 (file)
index 0000000..6cb62f0
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true" update-period="dummy">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentEmpty.xml b/tests/general/configs/BoxContentEmpty.xml
new file mode 100644 (file)
index 0000000..183ac21
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content/>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentMouseEventEmpty.xml b/tests/general/configs/BoxContentMouseEventEmpty.xml
new file mode 100644 (file)
index 0000000..c22f057
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html" mouse-event="">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentMouseEventWrongValue.xml b/tests/general/configs/BoxContentMouseEventWrongValue.xml
new file mode 100644 (file)
index 0000000..732ae52
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html" mouse-event="dummmy">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentMultipleBoxSize.xml b/tests/general/configs/BoxContentMultipleBoxSize.xml
new file mode 100644 (file)
index 0000000..d5412db
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+        <tizen:box-size>2x1</tizen:box-size>
+        <tizen:box-size>2x2</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentMultiplePd.xml b/tests/general/configs/BoxContentMultiplePd.xml
new file mode 100644 (file)
index 0000000..66e05e1
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index1.html" width="720" height="150" />
+         <tizen:pd src="pd/index2.html" width="720" height="150" />
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentNoMouseEvent.xml b/tests/general/configs/BoxContentNoMouseEvent.xml
new file mode 100644 (file)
index 0000000..aa7bb26
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentNoSrc.xml b/tests/general/configs/BoxContentNoSrc.xml
new file mode 100644 (file)
index 0000000..e41081a
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content>
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentNoTouchEfect.xml b/tests/general/configs/BoxContentNoTouchEfect.xml
new file mode 100644 (file)
index 0000000..aa7bb26
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentSrcEmpty.xml b/tests/general/configs/BoxContentSrcEmpty.xml
new file mode 100644 (file)
index 0000000..d14c7c7
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentTouchEfectEmpty.xml b/tests/general/configs/BoxContentTouchEfectEmpty.xml
new file mode 100644 (file)
index 0000000..d62bb8d
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html" touch-effect="">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxContentTouchEfectWrongValue.xml b/tests/general/configs/BoxContentTouchEfectWrongValue.xml
new file mode 100644 (file)
index 0000000..09fed1f
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html" touch-effect="dummy">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxIconEmpty.xml b/tests/general/configs/BoxIconEmpty.xml
new file mode 100644 (file)
index 0000000..42f3902
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-icon/>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxIconSrcEmpty.xml b/tests/general/configs/BoxIconSrcEmpty.xml
new file mode 100644 (file)
index 0000000..530f2bf
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-icon src="">
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxLabelEmpty.xml b/tests/general/configs/BoxLabelEmpty.xml
new file mode 100644 (file)
index 0000000..72e1c3b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label/>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxSizeEmpty.xml b/tests/general/configs/BoxSizeEmpty.xml
new file mode 100644 (file)
index 0000000..a8ac2b1
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxSizeNoUserDecoration.xml b/tests/general/configs/BoxSizeNoUserDecoration.xml
new file mode 100644 (file)
index 0000000..aa7bb26
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxSizePreviewEmpty.xml b/tests/general/configs/BoxSizePreviewEmpty.xml
new file mode 100644 (file)
index 0000000..c428737
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size preview="">1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/BoxSizeUserDecorationEmpty.xml b/tests/general/configs/BoxSizeUserDecorationEmpty.xml
new file mode 100644 (file)
index 0000000..5faf818
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size use-decoration="">1x1</tizen:box-size>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/ContentEmpty.xml b/tests/general/configs/ContentEmpty.xml
new file mode 100644 (file)
index 0000000..df27d2d
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/content" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.content" package="5154575452" required_version="1.0"/>
+  <tizen:content/>
+</widget>
diff --git a/tests/general/configs/ContentSrcCorrect.xml b/tests/general/configs/ContentSrcCorrect.xml
new file mode 100644 (file)
index 0000000..78155b0
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/content" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.content" package="5154575452" required_version="1.0"/>
+  <tizen:content src="http://test.org"/>
+</widget>
diff --git a/tests/general/configs/ContentSrcEmpty.xml b/tests/general/configs/ContentSrcEmpty.xml
new file mode 100644 (file)
index 0000000..3ac71ef
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/content" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.content" package="5154575452" required_version="1.0"/>
+  <tizen:content src=""/>
+</widget>
diff --git a/tests/general/configs/CspEmpty.xml b/tests/general/configs/CspEmpty.xml
new file mode 100644 (file)
index 0000000..a44c568
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:content-security-policy/>
+  <tizen:content-security-policy>anyCSP</tizen:content-security-policy>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/CspReportOnlyEmpty.xml b/tests/general/configs/CspReportOnlyEmpty.xml
new file mode 100644 (file)
index 0000000..a9a50d6
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:content-security-policy-report-only/>
+  <tizen:content-security-policy-report-only>anyCSP</tizen:content-security-policy-report-only>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/InstallConfig.xml b/tests/general/configs/InstallConfig.xml
new file mode 100644 (file)
index 0000000..7ee37d7
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?><widget id="http://test.samsung.com/widget/wac/tizen_appcontrol" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="AppControl">app-control</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <tizen:app-control>
+    <tizen:src name="edit1.html"/>
+    <tizen:operation name="http://tizen.org/appcontrol/operation/edit"/>
+    <tizen:mime name="image/jpg"/>
+  </tizen:app-control>
+  <tizen:app-control>
+    <tizen:src name="edit2.html"/>
+    <tizen:operation name="http://tizen.org/appcontrol/operation/view"/>
+    <tizen:mime name="audio/ogg"/>
+  </tizen:app-control>
+  <tizen:app-control>
+    <tizen:src name="edit3.html"/>
+    <tizen:operation name="http://tizen.org/appcontrol/operation/call"/>
+    <tizen:mime name="image/png"/>
+  </tizen:app-control>
+  <tizen:app-control>
+    <tizen:src name="edit4.html"/>
+    <tizen:operation name="http://tizen.org/appcontrol/operation/send"/>
+    <tizen:mime name="text/css"/>
+  </tizen:app-control>
+  <content src="index.html"/>
+<tizen:application id="6NfK1HgeJV.appcontrol" package="6NfK1HgeJV" required_version="1.0"/></widget>
diff --git a/tests/general/configs/MetadataDuplicatedKey.xml b/tests/general/configs/MetadataDuplicatedKey.xml
new file mode 100644 (file)
index 0000000..d48e5c2
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/metadata" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:metadata key="key1" value="value1"/>
+  <tizen:metadata key="key1" value="value2"/>
+  <tizen:application id="5154575452.metadata" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/MetadataEmpty.xml b/tests/general/configs/MetadataEmpty.xml
new file mode 100644 (file)
index 0000000..71ba7c3
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/metadata" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:metadata/>
+  <tizen:application id="5154575452.metadata" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/MultipleAllowNavigation.xml b/tests/general/configs/MultipleAllowNavigation.xml
new file mode 100644 (file)
index 0000000..97d63a6
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:allow-navigation>test1.org</tizen:allow-navigation>
+  <tizen:allow-navigation>test2.org test3.org</tizen:allow-navigation>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/MultipleContentCorrect.xml b/tests/general/configs/MultipleContentCorrect.xml
new file mode 100644 (file)
index 0000000..f9d5512
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/content" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.content" package="5154575452" required_version="1.0"/>
+  <tizen:content src="http://test.org"/>
+  <tizen:content src=""/>
+  <tizen:content src="http://test2222.org"/>
+  <tizen:content/>
+</widget>
diff --git a/tests/general/configs/MultipleContentIncorrect.xml b/tests/general/configs/MultipleContentIncorrect.xml
new file mode 100644 (file)
index 0000000..a9d45d4
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/content" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.content" package="5154575452" required_version="1.0"/>
+  <tizen:content src=""/>
+  <tizen:content src="http://test2222.org"/>
+  <tizen:content/>
+  <tizen:content src="http://test.org"/>
+</widget>
diff --git a/tests/general/configs/MultipleCsp.xml b/tests/general/configs/MultipleCsp.xml
new file mode 100644 (file)
index 0000000..6a5a362
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:content-security-policy>testCSP</tizen:content-security-policy>
+  <tizen:content-security-policy>anyCSP</tizen:content-security-policy>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/MultipleCspReportOnly.xml b/tests/general/configs/MultipleCspReportOnly.xml
new file mode 100644 (file)
index 0000000..48e5e8f
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:content-security-policy-report-only>testCSP</tizen:content-security-policy-report-only>
+  <tizen:content-security-policy-report-only>anyCSP</tizen:content-security-policy-report-only>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/MultipleMetadata.xml b/tests/general/configs/MultipleMetadata.xml
new file mode 100644 (file)
index 0000000..25fa227
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/metadata" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:metadata key="key1"/>
+  <tizen:metadata key="key2" value="value2"/>
+  <tizen:metadata key="key3" value="value3"/>
+  <tizen:application id="5154575452.metadata" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/NoAllowNavigation.xml b/tests/general/configs/NoAllowNavigation.xml
new file mode 100644 (file)
index 0000000..a6b2b12
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/NoContent.xml b/tests/general/configs/NoContent.xml
new file mode 100644 (file)
index 0000000..4bb8e41
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/content" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.content" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/NoCsp.xml b/tests/general/configs/NoCsp.xml
new file mode 100644 (file)
index 0000000..a6b2b12
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/NoMetadata.xml b/tests/general/configs/NoMetadata.xml
new file mode 100644 (file)
index 0000000..afab039
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/metadata" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:application id="5154575452.metadata" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdHeightEmpty.xml b/tests/general/configs/PdHeightEmpty.xml
new file mode 100644 (file)
index 0000000..f92cfb9
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="720" height=""/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdHeightExcessive.xml b/tests/general/configs/PdHeightExcessive.xml
new file mode 100644 (file)
index 0000000..825a64d
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="720" height="381"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdHeightTooLow.xml b/tests/general/configs/PdHeightTooLow.xml
new file mode 100644 (file)
index 0000000..aec51bc
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="720" height="0"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdHeightWrongValue.xml b/tests/general/configs/PdHeightWrongValue.xml
new file mode 100644 (file)
index 0000000..8ed5704
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="720" height="12dummy"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdNoHeight.xml b/tests/general/configs/PdNoHeight.xml
new file mode 100644 (file)
index 0000000..d90afdf
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="720"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdNoSrc.xml b/tests/general/configs/PdNoSrc.xml
new file mode 100644 (file)
index 0000000..f1e6490
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd width="720" height="150" />
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdNoWidth.xml b/tests/general/configs/PdNoWidth.xml
new file mode 100644 (file)
index 0000000..f6112a7
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html“ height="150" />
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdSrcEmpty.xml b/tests/general/configs/PdSrcEmpty.xml
new file mode 100644 (file)
index 0000000..af95f32
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="" width="720" height="150" />
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdWidthEmpty.xml b/tests/general/configs/PdWidthEmpty.xml
new file mode 100644 (file)
index 0000000..284daed
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="" height="150" />
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdWidthNegative.xml b/tests/general/configs/PdWidthNegative.xml
new file mode 100644 (file)
index 0000000..9699465
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="-1" height="524"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdWidthWrongValue.xml b/tests/general/configs/PdWidthWrongValue.xml
new file mode 100644 (file)
index 0000000..7b31656
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="1.2" height="524"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/PdWidthZero.xml b/tests/general/configs/PdWidthZero.xml
new file mode 100644 (file)
index 0000000..90e3711
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/appwidget" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:app-widget id="tizenScmgz.Sample.default" primary="true">
+    <tizen:box-label>My DynamicBox</tizen:box-label>
+    <tizen:box-content src="app-widget/index.html">
+        <tizen:box-size>1x1</tizen:box-size>
+         <tizen:pd src="pd/index.html" width="0" height="524"/>
+    </tizen:box-content>
+  </tizen:app-widget>
+  <tizen:application id="erj4675nvh.appwidget" package="erj4675nvh" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_category1.xml b/tests/general/configs/config_category1.xml
new file mode 100644 (file)
index 0000000..5f9d631
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <category name="testCategory1"/>
+  <category name="testCategory2"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_category2.xml b/tests/general/configs/config_category2.xml
new file mode 100644 (file)
index 0000000..45afbd7
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <category name=""/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_category3.xml b/tests/general/configs/config_category3.xml
new file mode 100644 (file)
index 0000000..4f33bb9
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <category/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_category4.xml b/tests/general/configs/config_category4.xml
new file mode 100644 (file)
index 0000000..46c1c0c
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <category name="testCategory1"/>
+  <category name="testCategory1"/>
+  <category name="testCategory2"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_privilege1.xml b/tests/general/configs/config_privilege1.xml
new file mode 100644 (file)
index 0000000..b97e685
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="privilege">privilege</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <tizen:privilege name="http://tizen.org/privilege/location"/>
+  <tizen:privilege name="http://tizen.org/privilege/notification"/>
+  <tizen:privilege name="http://tizen.org/privilege/mediacapture"/>
+  <tizen:privilege name="http://tizen.org/privilege/fullscreen"/>
+  <tizen:privilege name="http://tizen.org/privilege/unlimitedstorage"/>
+  <content src="index.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_privilege2.xml b/tests/general/configs/config_privilege2.xml
new file mode 100644 (file)
index 0000000..64491af
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="privilege">privilege</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <tizen:privilege name=""/>
+  <content src="index.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_privilege3.xml b/tests/general/configs/config_privilege3.xml
new file mode 100644 (file)
index 0000000..48dcf6f
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="privilege">privilege</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <tizen:privilege/>
+  <content src="index.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_privilege4.xml b/tests/general/configs/config_privilege4.xml
new file mode 100644 (file)
index 0000000..0578160
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="privilege">privilege</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <privilege name="http://tizen.org/privilege/location"/>
+  <content src="index.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_privilege5.xml b/tests/general/configs/config_privilege5.xml
new file mode 100644 (file)
index 0000000..4869c0b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="privilege">privilege</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <tizen:privilege name="http://tizen.org/privilege/location"/>
+  <tizen:privilege name="http://tizen.org/privilege/location"/>
+  <tizen:privilege name="http://tizen.org/privilege/notification"/>
+  <content src="index.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_privilege6.xml b/tests/general/configs/config_privilege6.xml
new file mode 100644 (file)
index 0000000..791e674
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <name short="privilege">privilege</name>
+  <icon height="75" src="icon.png" width="75"/>
+  <tizen:privilege name="//tizen.org/privilege/location"/>
+  <tizen:privilege name="http"/>
+  <tizen:privilege name="dummy"/>
+  <content src="index.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_splash1.xml b/tests/general/configs/config_splash1.xml
new file mode 100644 (file)
index 0000000..8604428
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:splash src="splash.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_splash2.xml b/tests/general/configs/config_splash2.xml
new file mode 100644 (file)
index 0000000..2a5653a
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:splash src=""/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_splash3.xml b/tests/general/configs/config_splash3.xml
new file mode 100644 (file)
index 0000000..7bc68cb
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <tizen:splash/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/configs/config_splash4.xml b/tests/general/configs/config_splash4.xml
new file mode 100644 (file)
index 0000000..c7682dc
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget id="http://test.samsung.com/widget/wac/privilege" min-version="1.0" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets">
+  <splash src="splash.html"/>
+  <tizen:application id="5154575452.privilege" package="5154575452" required_version="1.0"/>
+</widget>
diff --git a/tests/general/widgets/account.wgt b/tests/general/widgets/account.wgt
new file mode 100644 (file)
index 0000000..9d3592a
Binary files /dev/null and b/tests/general/widgets/account.wgt differ
diff --git a/tests/general/widgets/allowNavigation.wgt b/tests/general/widgets/allowNavigation.wgt
new file mode 100644 (file)
index 0000000..1ed6064
Binary files /dev/null and b/tests/general/widgets/allowNavigation.wgt differ
diff --git a/tests/general/widgets/app-control.wgt b/tests/general/widgets/app-control.wgt
new file mode 100644 (file)
index 0000000..cc98093
Binary files /dev/null and b/tests/general/widgets/app-control.wgt differ
diff --git a/tests/general/widgets/appWidgetFull.wgt b/tests/general/widgets/appWidgetFull.wgt
new file mode 100644 (file)
index 0000000..b228a23
Binary files /dev/null and b/tests/general/widgets/appWidgetFull.wgt differ
diff --git a/tests/general/widgets/appWidgetIncorrect.wgt b/tests/general/widgets/appWidgetIncorrect.wgt
new file mode 100644 (file)
index 0000000..5396411
Binary files /dev/null and b/tests/general/widgets/appWidgetIncorrect.wgt differ
diff --git a/tests/general/widgets/appWidgetMinimal.wgt b/tests/general/widgets/appWidgetMinimal.wgt
new file mode 100644 (file)
index 0000000..2a7aa5d
Binary files /dev/null and b/tests/general/widgets/appWidgetMinimal.wgt differ
diff --git a/tests/general/widgets/bg-00-with_bg.wgt b/tests/general/widgets/bg-00-with_bg.wgt
new file mode 100644 (file)
index 0000000..517a3e9
Binary files /dev/null and b/tests/general/widgets/bg-00-with_bg.wgt differ
diff --git a/tests/general/widgets/bg-01-missing_file.wgt b/tests/general/widgets/bg-01-missing_file.wgt
new file mode 100644 (file)
index 0000000..b14d665
Binary files /dev/null and b/tests/general/widgets/bg-01-missing_file.wgt differ
diff --git a/tests/general/widgets/bg-02-without_bg.wgt b/tests/general/widgets/bg-02-without_bg.wgt
new file mode 100644 (file)
index 0000000..ef45c95
Binary files /dev/null and b/tests/general/widgets/bg-02-without_bg.wgt differ
diff --git a/tests/general/widgets/category.wgt b/tests/general/widgets/category.wgt
new file mode 100644 (file)
index 0000000..abb0387
Binary files /dev/null and b/tests/general/widgets/category.wgt differ
diff --git a/tests/general/widgets/contentCorrect.wgt b/tests/general/widgets/contentCorrect.wgt
new file mode 100644 (file)
index 0000000..dd68ae2
Binary files /dev/null and b/tests/general/widgets/contentCorrect.wgt differ
diff --git a/tests/general/widgets/contentIncorrect.wgt b/tests/general/widgets/contentIncorrect.wgt
new file mode 100644 (file)
index 0000000..a0a7e07
Binary files /dev/null and b/tests/general/widgets/contentIncorrect.wgt differ
diff --git a/tests/general/widgets/csp.wgt b/tests/general/widgets/csp.wgt
new file mode 100644 (file)
index 0000000..10a7d2e
Binary files /dev/null and b/tests/general/widgets/csp.wgt differ
diff --git a/tests/general/widgets/inst_nplug_1.wgt b/tests/general/widgets/inst_nplug_1.wgt
new file mode 100644 (file)
index 0000000..8447f91
Binary files /dev/null and b/tests/general/widgets/inst_nplug_1.wgt differ
diff --git a/tests/general/widgets/inst_nplug_2.wgt b/tests/general/widgets/inst_nplug_2.wgt
new file mode 100644 (file)
index 0000000..6bb6cff
Binary files /dev/null and b/tests/general/widgets/inst_nplug_2.wgt differ
diff --git a/tests/general/widgets/inst_nplug_3.wgt b/tests/general/widgets/inst_nplug_3.wgt
new file mode 100644 (file)
index 0000000..4b30743
Binary files /dev/null and b/tests/general/widgets/inst_nplug_3.wgt differ
diff --git a/tests/general/widgets/inst_nplug_4.wgt b/tests/general/widgets/inst_nplug_4.wgt
new file mode 100644 (file)
index 0000000..a5ddecb
Binary files /dev/null and b/tests/general/widgets/inst_nplug_4.wgt differ
diff --git a/tests/general/widgets/manifest.wgt b/tests/general/widgets/manifest.wgt
new file mode 100644 (file)
index 0000000..874f044
Binary files /dev/null and b/tests/general/widgets/manifest.wgt differ
diff --git a/tests/general/widgets/metadata.wgt b/tests/general/widgets/metadata.wgt
new file mode 100644 (file)
index 0000000..b98f17d
Binary files /dev/null and b/tests/general/widgets/metadata.wgt differ
diff --git a/tests/general/widgets/privilege.wgt b/tests/general/widgets/privilege.wgt
new file mode 100644 (file)
index 0000000..5bb5f9a
Binary files /dev/null and b/tests/general/widgets/privilege.wgt differ
diff --git a/tests/general/widgets/splash.wgt b/tests/general/widgets/splash.wgt
new file mode 100644 (file)
index 0000000..79dcd49
Binary files /dev/null and b/tests/general/widgets/splash.wgt differ
diff --git a/tests/general/widgets/widgetFakeConfig.wgt b/tests/general/widgets/widgetFakeConfig.wgt
new file mode 100644 (file)
index 0000000..6d7af05
Binary files /dev/null and b/tests/general/widgets/widgetFakeConfig.wgt differ
diff --git a/tests/general/widgets/widgetInDir.tar b/tests/general/widgets/widgetInDir.tar
new file mode 100644 (file)
index 0000000..bf0830a
Binary files /dev/null and b/tests/general/widgets/widgetInDir.tar differ
diff --git a/tests/general/widgets/widgetUpdateVer100Signed.wgt b/tests/general/widgets/widgetUpdateVer100Signed.wgt
new file mode 100644 (file)
index 0000000..b3ff8bf
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer100Signed.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer100Unsigned.wgt b/tests/general/widgets/widgetUpdateVer100Unsigned.wgt
new file mode 100644 (file)
index 0000000..751aed0
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer100Unsigned.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220Signed.wgt b/tests/general/widgets/widgetUpdateVer220Signed.wgt
new file mode 100644 (file)
index 0000000..5ef42af
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220Signed.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt b/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt
new file mode 100644 (file)
index 0000000..c1aeaa3
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220Unsigned.wgt b/tests/general/widgets/widgetUpdateVer220Unsigned.wgt
new file mode 100644 (file)
index 0000000..181447d
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220Unsigned.wgt differ
diff --git a/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt b/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt
new file mode 100644 (file)
index 0000000..8fb6c19
Binary files /dev/null and b/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt differ
diff --git a/uncrustify.cfg b/uncrustify.cfg
new file mode 100644 (file)
index 0000000..2bf1d96
--- /dev/null
@@ -0,0 +1,170 @@
+indent_align_string=true\r
+indent_braces=false\r
+indent_braces_no_func=false\r
+indent_brace_parent=false\r
+indent_namespace=false\r
+indent_extern=false\r
+indent_class=true\r
+indent_class_colon=false\r
+indent_else_if=false\r
+indent_func_call_param=false\r
+indent_func_def_param=false\r
+indent_func_proto_param=false\r
+indent_func_class_param=false\r
+indent_func_ctor_var_param=false\r
+indent_template_param=false\r
+indent_func_param_double=false\r
+indent_relative_single_line_comments=false\r
+indent_col1_comment=true\r
+indent_access_spec_body=false\r
+indent_paren_nl=false\r
+indent_comma_paren=false\r
+indent_bool_paren=false\r
+indent_square_nl=false\r
+indent_preserve_sql=false\r
+indent_align_assign=false\r
+sp_balance_nested_parens=false\r
+align_keep_tabs=false\r
+align_with_tabs=false\r
+align_on_tabstop=false\r
+align_number_left=false\r
+align_func_params=false\r
+align_same_func_call_params=false\r
+align_var_def_colon=false\r
+align_var_def_attribute=false\r
+align_var_def_inline=false\r
+align_right_cmt_mix=false\r
+align_on_operator=false\r
+align_mix_var_proto=false\r
+align_single_line_func=false\r
+align_single_line_brace=false\r
+align_nl_cont=false\r
+align_left_shift=true\r
+nl_collapse_empty_body=true\r
+nl_assign_leave_one_liners=false\r
+nl_class_leave_one_liners=false\r
+nl_enum_leave_one_liners=false\r
+nl_getset_leave_one_liners=false\r
+nl_func_leave_one_liners=false\r
+nl_if_leave_one_liners=false\r
+nl_multi_line_cond=true\r
+nl_multi_line_define=false\r
+nl_before_case=false\r
+nl_after_case=false\r
+nl_after_return=false\r
+nl_after_semicolon=true\r
+nl_after_brace_open=false\r
+nl_after_brace_open_cmt=false\r
+nl_after_vbrace_open=false\r
+nl_after_brace_close=false\r
+nl_define_macro=false\r
+nl_squeeze_ifdef=false\r
+nl_ds_struct_enum_cmt=false\r
+nl_ds_struct_enum_close_brace=false\r
+nl_create_if_one_liner=false\r
+nl_create_for_one_liner=false\r
+nl_create_while_one_liner=false\r
+ls_for_split_full=true\r
+ls_func_split_full=true\r
+nl_after_multiline_comment=false\r
+eat_blanks_after_open_brace=true\r
+eat_blanks_before_close_brace=true\r
+mod_pawn_semicolon=false\r
+mod_full_paren_if_bool=false\r
+mod_remove_extra_semicolon=true\r
+mod_sort_import=false\r
+mod_sort_using=false\r
+mod_sort_include=false\r
+mod_move_case_break=false\r
+mod_remove_empty_return=false\r
+cmt_indent_multi=true\r
+cmt_c_group=false\r
+cmt_c_nl_start=false\r
+cmt_c_nl_end=false\r
+cmt_cpp_group=false\r
+cmt_cpp_nl_start=false\r
+cmt_cpp_nl_end=false\r
+cmt_cpp_to_c=false\r
+cmt_star_cont=true\r
+cmt_multi_check_last=true\r
+cmt_insert_before_preproc=false\r
+pp_indent_at_level=false\r
+pp_region_indent_code=false\r
+pp_if_indent_code=false\r
+pp_define_at_level=false\r
+indent_columns=4\r
+indent_member=4\r
+indent_access_spec=-2\r
+code_width=80\r
+nl_max=2\r
+nl_before_access_spec=2\r
+cmt_width=80\r
+indent_with_tabs=0\r
+sp_arith=force\r
+sp_assign=force\r
+sp_enum_assign=force\r
+sp_pp_concat=remove\r
+sp_pp_stringify=remove\r
+sp_bool=force\r
+sp_compare=force\r
+sp_paren_brace=force\r
+sp_angle_paren=remove\r
+sp_before_sparen=force\r
+sp_inside_sparen=remove\r
+sp_after_sparen=force\r
+sp_sparen_brace=force\r
+sp_before_semi=remove\r
+sp_after_semi_for_empty=remove\r
+sp_before_square=remove\r
+sp_before_squares=remove\r
+sp_inside_square=remove\r
+sp_after_comma=force\r
+sp_before_comma=remove\r
+sp_after_class_colon=force\r
+sp_before_class_colon=force\r
+sp_before_case_colon=remove\r
+sp_inside_braces=add\r
+sp_inside_fparens=remove\r
+sp_inside_fparen=remove\r
+sp_func_call_paren=remove\r
+sp_func_class_paren=remove\r
+sp_else_brace=force\r
+sp_brace_else=force\r
+sp_catch_brace=force\r
+sp_brace_catch=force\r
+sp_try_brace=force\r
+sp_before_dc=remove\r
+sp_after_dc=remove\r
+sp_not=remove\r
+sp_inv=remove\r
+sp_addr=remove\r
+sp_member=remove\r
+sp_deref=remove\r
+sp_sign=remove\r
+sp_incdec=remove\r
+sp_cond_colon=force\r
+sp_cond_question=force\r
+sp_case_label=force\r
+nl_assign_brace=remove\r
+nl_if_brace=remove\r
+nl_brace_else=remove\r
+nl_elseif_brace=remove\r
+nl_else_brace=remove\r
+nl_else_if=remove\r
+nl_try_brace=remove\r
+nl_for_brace=remove\r
+nl_catch_brace=remove\r
+nl_brace_catch=remove\r
+nl_while_brace=remove\r
+nl_do_brace=remove\r
+nl_brace_while=remove\r
+nl_switch_brace=remove\r
+nl_namespace_brace=remove\r
+nl_class_brace=force\r
+nl_fdef_brace=force\r
+pos_class_comma=trail\r
+pos_class_colon=trail\r
+mod_full_brace_do=add\r
+mod_full_brace_for=add\r
+mod_full_brace_if=add\r
+mod_full_brace_while=add\r
diff --git a/uncrustify.sh b/uncrustify.sh
new file mode 100755 (executable)
index 0000000..49ad3cf
--- /dev/null
@@ -0,0 +1 @@
+uncrustify -c uncrustify.cfg --no-backup `find . -regex "\(.*\.cpp\|.*\.h\|.*\.c\|.*\.cc\)" | grep -v "orm.h\|orm_generator.h\|3rdparty\|examples"`
diff --git a/wrt-installer.manifest b/wrt-installer.manifest
new file mode 100644 (file)
index 0000000..eccc16f
--- /dev/null
@@ -0,0 +1,14 @@
+<manifest>
+  <define>
+    <domain name="wrt-installer" />
+    <provide>
+      <label name="wrt-installer::installer" />
+    </provide>
+  </define>
+  <request>
+    <domain name="_" />
+  </request>
+  <assign>
+      <filesystem path="/usr/bin/wrt-installer" label="wrt-installer" exec_label="wrt-installer"/>
+  </assign>
+</manifest>
diff --git a/wrt-installer.rule b/wrt-installer.rule
new file mode 100644 (file)
index 0000000..68ce76f
--- /dev/null
@@ -0,0 +1 @@
+wrt-installer aul::terminate x