--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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/
+)
+
+
--- /dev/null
+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.
--- /dev/null
+# 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)
+
--- /dev/null
+FILE(GLOB XSD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.xsd")
+INSTALL(FILES ${XSD_FILES} DESTINATION /usr/etc/wrt-installer/)
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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
--- /dev/null
+<?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 -->
--- /dev/null
+<?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>
--- /dev/null
+#!/bin/sh
+xmllint --schema widgets.xsd config.xml
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+#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
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
--- /dev/null
+!!!options!!! stop
+Widget (un)installer, plugin (un)installer
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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");
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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()
+{}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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);
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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());
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * 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;
+}
+}
--- /dev/null
+/*
+ * 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_ */
+
--- /dev/null
+/*
+ * 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;
+}
+}
--- /dev/null
+/*
+ * 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_ */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * 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(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ _D("Regcomp failed");
+ }
+
+ _D("Name : %ls", (*name).c_str());
+ if (!name || (regexec(®x, 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(®x);
+ _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_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ _D("Regcomp failed");
+ return false;
+ }
+
+ if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
+ == REG_NOMATCH)
+ {
+ regfree(®);
+ return false;
+ }
+ regfree(®);
+ return true;
+}
+
+bool TaskConfiguration::validateTizenPackageID(
+ const WrtDB::TizenPkgId &tizenPkgId)
+{
+ _D("tizen application ID = [%ls]", tizenPkgId.c_str());
+
+ regex_t reg;
+ if (regcomp(®, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0)
+ {
+ _D("Regcomp failed");
+ return false;
+ }
+ if (regexec(®, DPL::ToUTF8String(tizenPkgId).c_str(), 0, NULL, 0) == REG_NOMATCH)
+ {
+ regfree(®);
+ return false;
+ }
+ regfree(®);
+ 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;
+}
+
+}
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 µVersion) 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 µVersion) 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+{
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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(®x, REG_TIZEN_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
+ _D("Regcomp failed");
+ }
+ std::string pkgId;
+ DPL::Utils::Path installPath;
+
+ Try {
+ if ((regexec(®x, 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+}
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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");
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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");
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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";
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+#
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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)
--- /dev/null
+Executables for interfacing with the package manager
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ _D("Regcomp failed");
+ }
+
+ WrtDB::TizenAppId appid;
+
+ if (!(regexec(®, 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
--- /dev/null
+!!!options!!! stop
+Widget (un)installer, plugin (un)installer
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_ */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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");
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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()
+{}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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());
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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);
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * 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;
+}
+}
--- /dev/null
+/*
+ * 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_ */
+
--- /dev/null
+/*
+ * 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;
+}
+}
--- /dev/null
+/*
+ * 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_ */
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+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)
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * 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(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ _D("Regcomp failed");
+ }
+
+ _D("Name : %ls", (*name).c_str());
+ if (!name || (regexec(®x, 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(®x);
+ _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_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ _D("Regcomp failed");
+ return false;
+ }
+
+ if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
+ == REG_NOMATCH)
+ {
+ regfree(®);
+ return false;
+ }
+ regfree(®);
+ return true;
+}
+
+bool TaskConfiguration::validateTizenPackageID(
+ const WrtDB::TizenPkgId &tizenPkgId)
+{
+ _D("tizen application ID = [%ls]", tizenPkgId.c_str());
+
+ regex_t reg;
+ if (regcomp(®, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0)
+ {
+ _D("Regcomp failed");
+ return false;
+ }
+ if (regexec(®, DPL::ToUTF8String(tizenPkgId).c_str(), 0, NULL, 0) == REG_NOMATCH)
+ {
+ regfree(®);
+ return false;
+ }
+ regfree(®);
+ 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;
+}
+
+}
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 µVersion) 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 µVersion) 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+ /*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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)
+{
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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(®x, REG_TIZEN_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){
+ _D("Regcomp failed");
+ }
+ std::string pkgId = id;
+ DPL::Utils::Path installPath;
+ if ((regexec(®x, 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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;
+}
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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");
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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");
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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";
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+#
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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)
--- /dev/null
+Executables for interfacing with the package manager
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ _D("Regcomp failed");
+ }
+
+ WrtDB::TizenAppId appid;
+
+ if (!(regexec(®, 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_
--- /dev/null
+# Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES 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)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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();
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_ */
--- /dev/null
+# 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)
--- /dev/null
+/*
+ * 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!");
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+# 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/)
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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);
+}
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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
--- /dev/null
+/*
+ * 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));
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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"*")));
+}
--- /dev/null
+/*
+ * 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")));
+ );
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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")));
+ );
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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")));
+// );
+//}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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 ####");
+}
--- /dev/null
+/*
+ * 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());
+}
--- /dev/null
+/*
+ * 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)
--- /dev/null
+/*
+ * 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!");
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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));
+}
--- /dev/null
+/*
+ * 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()));
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+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
--- /dev/null
+uncrustify -c uncrustify.cfg --no-backup `find . -regex "\(.*\.cpp\|.*\.h\|.*\.c\|.*\.cc\)" | grep -v "orm.h\|orm_generator.h\|3rdparty\|examples"`
--- /dev/null
+<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>
--- /dev/null
+wrt-installer aul::terminate x