From 5d0b581548563b0b271382c1aedb900ff055cd42 Mon Sep 17 00:00:00 2001 From: Jihoon Chung Date: Thu, 3 Jan 2013 10:50:16 +0900 Subject: [PATCH] [Release] wrt-installer_0.0.89 --- .gitignore | 3 + configuration/config.tizen.xsd | 143 ++++- configuration/config.xml | 37 +- configuration/config.xsd | 12 +- debian/changelog | 175 +++++++ etc/CMakeLists.txt | 7 - etc/drm/armv7l/libdrm-service-core-intel.so | 1 - etc/drm/armv7l/libdrm-service-core-intel.so.0 | 1 - etc/drm/armv7l/libdrm-service-core-intel.so.0.0.0 | Bin 28860 -> 0 bytes etc/drm/ix86/libdrm-service-core-intel.so | 1 - etc/drm/ix86/libdrm-service-core-intel.so.0 | 1 - etc/drm/ix86/libdrm-service-core-intel.so.0.0.0 | Bin 39076 -> 0 bytes etc/wrt_preinstall_widgets.sh | 4 +- packaging/wrt-installer.spec | 50 +- packaging/wrt-preinstall-widgets.service | 8 + src/CMakeLists.txt | 54 +- src/commons/drm/CPointerArray.h | 52 -- src/commons/drm/CXMLAttribute.h | 37 -- src/commons/drm/CXMLElement.h | 57 -- src/commons/drm/CXMLFile.h | 54 -- src/commons/drm/InkaTypes.h | 76 --- src/commons/drm/IntelDrm_Core.h | 46 -- src/commons/drm/drm-intel-crypto-util.h | 13 - src/commons/drm/drm-intel-util.h | 69 --- src/commons/drm/drm-oem-intel.h | 172 ------ src/commons/wrt_common_types.h | 8 + src/configuration_parser/widget_parser.cpp | 581 ++++++++++++++++++--- src/configuration_parser/widget_parser.h | 6 +- src/jobs/widget_install/ace_registration.cpp | 139 +++++ src/jobs/widget_install/ace_registration.h | 36 ++ src/jobs/widget_install/job_widget_install.cpp | 302 +++++++---- src/jobs/widget_install/job_widget_install.h | 9 +- src/jobs/widget_install/manifest.cpp | 93 +++- src/jobs/widget_install/manifest.h | 73 ++- src/jobs/widget_install/task_certificates.cpp | 79 ++- src/jobs/widget_install/task_certify.cpp | 47 +- src/jobs/widget_install/task_commons.cpp | 9 +- src/jobs/widget_install/task_commons.h | 3 +- src/jobs/widget_install/task_database.cpp | 144 ++++- src/jobs/widget_install/task_database.h | 14 +- src/jobs/widget_install/task_db_update.cpp | 121 ----- src/jobs/widget_install/task_db_update.h | 47 -- src/jobs/widget_install/task_encrypt_resource.cpp | 13 +- src/jobs/widget_install/task_file_manipulation.cpp | 255 ++++++++- src/jobs/widget_install/task_file_manipulation.h | 12 +- src/jobs/widget_install/task_manifest_file.cpp | 148 +++++- src/jobs/widget_install/task_manifest_file.h | 4 + src/jobs/widget_install/task_new_db_insert.cpp | 111 ---- src/jobs/widget_install/task_new_db_insert.h | 48 -- src/jobs/widget_install/task_private_storage.cpp | 125 ----- src/jobs/widget_install/task_recovery.cpp | 4 - src/jobs/widget_install/task_unzip.cpp | 4 + src/jobs/widget_install/task_widget_config.cpp | 42 +- src/jobs/widget_install/task_widget_config.h | 1 + src/jobs/widget_install/wac_security.cpp | 7 - src/jobs/widget_install/wac_security.h | 3 - src/jobs/widget_install/widget_install_context.h | 3 +- src/jobs/widget_install/widget_install_errors.h | 5 + src/jobs/widget_install/widget_installer_struct.h | 19 +- src/jobs/widget_install/widget_unzip.cpp | 210 -------- src/jobs/widget_install/widget_unzip.h | 59 --- src/jobs/widget_uninstall/job_widget_uninstall.cpp | 24 +- src/jobs/widget_uninstall/job_widget_uninstall.h | 1 + src/jobs/widget_uninstall/task_db_update.cpp | 6 + src/jobs/widget_uninstall/task_remove_files.cpp | 50 +- src/jobs/widget_uninstall/task_remove_files.h | 2 + src/jobs/widget_uninstall/uninstaller_context.h | 1 + .../widget_uninstall/widget_uninstaller_struct.h | 24 +- src/logic/installer_controller.h | 2 +- src/misc/widget_install_to_external.cpp | 134 +++++ src/misc/widget_install_to_external.h | 59 +++ src/misc/widget_location.cpp | 57 +- src/misc/widget_location.h | 17 +- src/pkg-manager/pkgmgr_signal.cpp | 6 +- src/pkg-manager/pkgmgr_signal.h | 22 +- src/pkg-manager/pkgmgr_signal_dummy.h | 57 ++ .../pkgmgr_signal_interface.h} | 40 +- src/wrt-installer/wrt_installer.cpp | 142 +++-- src/wrt-installer/wrt_installer.h | 8 +- src/wrt-installer/wrt_installer_api.cpp | 44 +- src/wrt-installer/wrt_installer_api.h | 25 +- 81 files changed, 2740 insertions(+), 1838 deletions(-) create mode 100644 .gitignore mode change 100644 => 100755 configuration/config.tizen.xsd mode change 100644 => 100755 configuration/config.xml mode change 100644 => 100755 configuration/config.xsd delete mode 120000 etc/drm/armv7l/libdrm-service-core-intel.so delete mode 120000 etc/drm/armv7l/libdrm-service-core-intel.so.0 delete mode 100755 etc/drm/armv7l/libdrm-service-core-intel.so.0.0.0 delete mode 120000 etc/drm/ix86/libdrm-service-core-intel.so delete mode 120000 etc/drm/ix86/libdrm-service-core-intel.so.0 delete mode 100755 etc/drm/ix86/libdrm-service-core-intel.so.0.0.0 create mode 100644 packaging/wrt-preinstall-widgets.service delete mode 100755 src/commons/drm/CPointerArray.h delete mode 100755 src/commons/drm/CXMLAttribute.h delete mode 100755 src/commons/drm/CXMLElement.h delete mode 100755 src/commons/drm/CXMLFile.h delete mode 100755 src/commons/drm/InkaTypes.h delete mode 100755 src/commons/drm/IntelDrm_Core.h delete mode 100755 src/commons/drm/drm-intel-crypto-util.h delete mode 100755 src/commons/drm/drm-intel-util.h delete mode 100755 src/commons/drm/drm-oem-intel.h create mode 100644 src/jobs/widget_install/ace_registration.cpp create mode 100644 src/jobs/widget_install/ace_registration.h mode change 100644 => 100755 src/jobs/widget_install/manifest.cpp mode change 100644 => 100755 src/jobs/widget_install/manifest.h delete mode 100644 src/jobs/widget_install/task_db_update.cpp delete mode 100644 src/jobs/widget_install/task_db_update.h mode change 100644 => 100755 src/jobs/widget_install/task_manifest_file.cpp mode change 100644 => 100755 src/jobs/widget_install/task_manifest_file.h delete mode 100644 src/jobs/widget_install/task_new_db_insert.cpp delete mode 100644 src/jobs/widget_install/task_new_db_insert.h delete mode 100644 src/jobs/widget_install/task_private_storage.cpp delete mode 100644 src/jobs/widget_install/widget_unzip.cpp delete mode 100644 src/jobs/widget_install/widget_unzip.h create mode 100644 src/misc/widget_install_to_external.cpp create mode 100644 src/misc/widget_install_to_external.h create mode 100644 src/pkg-manager/pkgmgr_signal_dummy.h rename src/{jobs/widget_install/task_private_storage.h => pkg-manager/pkgmgr_signal_interface.h} (50%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..306ad56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*~ +\#*# +.#* \ No newline at end of file diff --git a/configuration/config.tizen.xsd b/configuration/config.tizen.xsd old mode 100644 new mode 100755 index a981896..46adddc --- a/configuration/config.tizen.xsd +++ b/configuration/config.tizen.xsd @@ -1,10 +1,10 @@ - - + + - @@ -38,6 +38,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -57,10 +93,101 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/configuration/config.xml b/configuration/config.xml old mode 100644 new mode 100755 index 4038a23..3e5dc15 --- a/configuration/config.xml +++ b/configuration/config.xml @@ -1,23 +1,23 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + hello @@ -32,4 +32,5 @@ + diff --git a/configuration/config.xsd b/configuration/config.xsd old mode 100644 new mode 100755 index 84d734d..07d19e8 --- a/configuration/config.xsd +++ b/configuration/config.xsd @@ -49,6 +49,11 @@ + + + + + @@ -68,10 +73,11 @@ + - + @@ -79,7 +85,7 @@ - + @@ -154,8 +160,6 @@ - - diff --git a/debian/changelog b/debian/changelog index e5a18b9..a9505da 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,178 @@ +wrt-installer (0.0.89) unstable; urgency=low + + * Throw error on no ElementParser + * Closed directory + * Apply vconf key path builder + * Add vconf creation for memory saving mode + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.89 + + -- Jihoon Chung Wed, 02 Jan 2013 11:17:14 +0900 + +wrt-installer (0.0.88) unstable; urgency=low + + * Create/Remove vconf for security settings + * Remove required attribute and viewmode Change windowed to maximized + * auto-launch tag has been changed + * livebox configuration valuables has been modified + * For livebox configuration + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.88 + + -- Jihoon Chung Fri, 28 Dec 2012 16:59:20 +0900 + +wrt-installer (0.0.86) unstable; urgency=low + + * Add installation to external location(sdcard) + * Remove installed directory and manifest file when installation failed after ace check + * Fixed directory installation using pkgcmd + * Fixed crash for external installation + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.86 + + -- Soyoung Kim Wed, 26 Dec 2012 13:45:45 +0900 + +wrt-installer (0.0.85) unstable; urgency=low + + * Add category element at manifest and config.xml + + -- KEONGEUN Fri, 21 Dec 2012 16:48:54 +0900 + +wrt-installer (0.0.84) unstable; urgency=low + + * Fix for unhandled exception + * Dummy PkgmgrSignal for command line installation + * Support privilege database table + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.84 + + -- Jihoon Chung Thu, 20 Dec 2012 08:49:25 +0900 + +wrt-installer (0.0.83) unstable; urgency=low + + * Handle unhandled exceptions in wrt-installer + * Support + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.83 + + -- Jihoon Chung Fri, 14 Dec 2012 10:47:26 +0900 + +wrt-installer (0.0.82) unstable; urgency=low + + * Fixed build break + * [systemd] fix build error + * Directory install feature fix + * Update schema files + * [Prevent] Removed warning from Prevent. + * [Prevent] Removed warning from Prevent. + * Fixed package manager doesn't receive signal for widget update failed. + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.82 + + -- Soyoung Kim Wed, 12 Dec 2012 15:50:01 +0900 + +wrt-installer (0.0.81) unstable; urgency=low + + * Merge branch 'systemd' + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.81 + + -- Soyoung Kim Thu, 06 Dec 2012 14:02:20 +0900 + +wrt-installer (0.0.80) unstable; urgency=low + + * Distinguish between system headers and project headers. + * Add nodisplay setting + * arrangement of directory creation. + * add to create share directory + * Fixed nodisplay when other setting values exist. + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.80 + + -- Soyoung Kim Wed, 05 Dec 2012 17:23:51 +0900 + +wrt-installer (0.0.79) unstable; urgency=low + + * Direcotry install feature added to wrt-installer + * [Prevent] Handle return value of regcomp. + * Removing unused merged code + * Pkgname (tizen id) - not null + * Platform version check during wgt installation - fixed + * Revert "Pkgname (tizen id) - not null" + * save installed path to db for preload widget + * Fixed certificate of authentication value to base64. + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.79 + + -- Soyoung Kim Fri, 30 Nov 2012 21:44:41 +0900 + +wrt-installer (0.0.78) unstable; urgency=low + + * [Prevent] Handle fread return value. + * [Prevent] Handle return value from CertificateCollection::sort. + * remove temporary drm library and header files. + * [Installer] Clean up Flash Parser. + * Fixed can't remove preinstall widget during booting + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.78 + + -- Soyoung Kim Tue, 27 Nov 2012 16:51:00 +0900 + +wrt-installer (0.0.77) unstable; urgency=low + + * Revert "Platform version check during wgt installation" + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.77 + + -- Soyoung Kim Fri, 23 Nov 2012 21:19:17 +0900 + +wrt-installer (0.0.76) unstable; urgency=low + + * Filter output from wrt-installer needs for "expr match" to succeed + * Introduce systemd support + * Removed deprecated code + * Handle return value + * Platform version check during wgt installation + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.76 + + -- Jihoon Chung Fri, 23 Nov 2012 12:01:17 +0900 + +wrt-installer (0.0.75) unstable; urgency=low + + * Fail to install package + * External file removal fix + * Removed GetFactoryWidget. + * Ace database fulfill implemented + * update drm library for temporary + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.75 + + -- sy037.kim Mon, 19 Nov 2012 19:56:28 +0900 + +wrt-installer (0.0.74) unstable; urgency=low + + * Replace SignatureValidator. + * Fixed to set certi information + + * Git : framework/web/wrt-installer + * Tag : wrt-installer_0.0.74 + + -- Soyoung Kim Thu, 15 Nov 2012 16:46:02 +0900 + wrt-installer (0.0.73) unstable; urgency=low * WidgetHandle removal - part 4 diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt index adccb68..370d4af 100644 --- a/etc/CMakeLists.txt +++ b/etc/CMakeLists.txt @@ -1,10 +1,3 @@ SET(ETC_DIR ${PROJECT_SOURCE_DIR}/etc) INSTALL(PROGRAMS ${ETC_DIR}/wrt_preinstall_widgets.sh DESTINATION /etc/rc.d/init.d) - -# Below Code is temporary. When DRM engine is provided it will be removed. -IF("${ARCH}" MATCHES "arm") - INSTALL(FILES ${ETC_DIR}/drm/armv7l/libdrm-service-core-intel.so.0.0.0 DESTINATION lib) -ELSE("${ARCH}" MATCHES "arm") - INSTALL(FILES ${ETC_DIR}/drm/ix86/libdrm-service-core-intel.so.0.0.0 DESTINATION lib) -ENDIF("${ARCH}" MATCHES "arm") diff --git a/etc/drm/armv7l/libdrm-service-core-intel.so b/etc/drm/armv7l/libdrm-service-core-intel.so deleted file mode 120000 index df92fda..0000000 --- a/etc/drm/armv7l/libdrm-service-core-intel.so +++ /dev/null @@ -1 +0,0 @@ -libdrm-service-core-intel.so.0 \ No newline at end of file diff --git a/etc/drm/armv7l/libdrm-service-core-intel.so.0 b/etc/drm/armv7l/libdrm-service-core-intel.so.0 deleted file mode 120000 index 4af898f..0000000 --- a/etc/drm/armv7l/libdrm-service-core-intel.so.0 +++ /dev/null @@ -1 +0,0 @@ -libdrm-service-core-intel.so.0.0.0 \ No newline at end of file diff --git a/etc/drm/armv7l/libdrm-service-core-intel.so.0.0.0 b/etc/drm/armv7l/libdrm-service-core-intel.so.0.0.0 deleted file mode 100755 index 68b76cf4cd32b54e05c00c2307b673e7e25854f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28860 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 diff --git a/etc/drm/ix86/libdrm-service-core-intel.so b/etc/drm/ix86/libdrm-service-core-intel.so deleted file mode 120000 index df92fda..0000000 --- a/etc/drm/ix86/libdrm-service-core-intel.so +++ /dev/null @@ -1 +0,0 @@ -libdrm-service-core-intel.so.0 \ No newline at end of file diff --git a/etc/drm/ix86/libdrm-service-core-intel.so.0 b/etc/drm/ix86/libdrm-service-core-intel.so.0 deleted file mode 120000 index 4af898f..0000000 --- a/etc/drm/ix86/libdrm-service-core-intel.so.0 +++ /dev/null @@ -1 +0,0 @@ -libdrm-service-core-intel.so.0.0.0 \ No newline at end of file diff --git a/etc/drm/ix86/libdrm-service-core-intel.so.0.0.0 b/etc/drm/ix86/libdrm-service-core-intel.so.0.0.0 deleted file mode 100755 index d21a059c6372110cbc38e8c05528a163eb994a80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39076 zcmeHwe_T{m`u`mm6%`#aDr~JCi;PMU%uEaogu!1>q+s^LMub5~1cJfTj~FzJI(wUz zN?o`0v)T5`er&m0>zY}iuu!d)nU(EYQBe)amX(>AHQ)F9oO@^P3v-;S&U2pgoacGYbDneVW$taZ+#Hk1r07?)60H!*KVMNMA|JIu)=X5a%0MMaIY${K z>UDhPHNTc=0D(9~);Hr`OGl#=Bpls8fnH=h03?%uYC5MzuYnG#%tf(Ta;GY`ROj#^F^rp zFQijEyK;(NH(OKk)|U>x@u5ZY^b;u z_hXR;Bb6eZkF*5oDkKb7Nkii0M7j_u0jU6KAyOUESxDoME-Jg)v&$un2X=qWJ)RVJH}Zd)jp}QkGUeSIhOR z95*wOrXpR7G!iKmiS~95QaaKvk@TxdyGhgwv^)>_G(*{B?S3?JGg6MBZn5G1Qp3IR zcD4o#H5A%$e}x9m((==^+^XeMkkkJ4Yoc~@3-VFgeFgGNq~#jSIXywU?<+e`t5|73 zxC!?+XfWp_WlULfzR~X6Fq2}{l<4viDGgJ$PCh3C)3Ld!D<)~dxfW%ARP*goqZ5E^ zJ*5oT>QR~p{vmU4voAVoaMa)&+lPZPNJdWtS_NVHAPnQM^ri?+f!NxPg2Xvb+u}vP zL76W@szjm;M}yKGy7^PgKbJ$cQmkEK3b zVTa@NIZo!-x{v>(b*7F7@Xah>{)+n$Nvu_5l^UDxc}^mOT| zgiTNW_lZxAOio$;yURW=e&*Gjci#BNc}W|)|9)}W=Wl*FJZiZ8gLP9}a|`x4C!KTu zrYHB;H>C}VzU9TID>vWstoN(oE59}W`ut7y4<3DU+}g1}Y_NX0X55GwSGsrA-#qPo z$18&;ChfmC?Tj>Kq4SwXELkJ$A7l?s9rfDR$2Tr~Xw#ERI^4Uqy!ZXvh0{7y?6bW) z2i|($g~j*UKZu|A&L1O zZ+h~;#P0TYZ&{$5JESPDTTJ?$qKv?8o9X#Ka`39#&{4)#<2!EnG zY1|X;34=Xh{cQ?se_j~89yIie^qvo^e=H0h#!07L#Q%d1ASWC}N2Fb+A*b!?7wb3b z0CK{w8Sn{j59`ktHlER8{g0w!(Jr=MNvEn^gwF|s$A`85osNv0`1gg$e?(aS!^8O7 z5eB~!M*oMf_P-Cq|3z4Tt}uR%h3WTD7`-RL;Jsn==W%h;E{-od3_cJhpEGr2I)7Z{|mSg^(m+yt-JoP9xh_ExJ3A4@Xh|`A>WQgCr_hKyc3%9 z9-$0VD$%|(RZ+MuiSdHJMc{vx2G?O=`PsnH`Y!{&&6g?4Fby6I_+CT*-=e>2@TbdT z3T`?f&vFg_0O_3z;)4DV5x>P@G5Z!l1N%<{KU=|%uI~w;zXJ5+_|8xYp})B6F|QEt z5Pu=`5m&7!>(Gwy)wHiG6lI>EAFJGf`UWgyW3>J+LY@L;@6zg%!sIg#_1jBPiE`50 z1G)_m&IKC&wPEsl2rz}m^^f>IEn9~{VO|Jn+r_|AF=k z&>r0id%Y6lU1Xql5%9L(tSGN&4`zHbJ7 z<9t4a`i5zW@)78eAMOo}@_HBJU2ov;5y-;I#$@hf)wl4Vtu_F89A zjni&d?4{+EvRaUR<_RDXpqTtI}I*%AF3Sw78*S6-W4vn;2)0)nI5YKqHhm{%4T)jHUswAO)fltR)K$}-5g zs#qzlaX>ybj-nFM3sXmlqqt^ewbNc*RJ^ok38>D4cCSxOBWoqarS>v3bJT!K!F%fE zva}QoXjPg{s#gjz^cs~AJ9Q|t}S7@agR+fiIq;-KWEN+Ph4Usj$Uu|IHE;;3*q zrJV@biC!X%uDGhQwr-gtXl%d<*Kk=;t$jHxxFiJYs?*p{Pl z!Thjtl$8|av#M8%RMDbWaf&D|sfgGpOLi09C@V6pOEXJKY=TZ@(ajN9m^4>ds*N%Z zCwb`%hf`D(%<4U)f_V|j=3kYX!YRL^XmR=S)YQvy&slDFuB@giN~>&IHw*G|Go8+w z^2K#dhf!|E@<^z`K^if$rNGF)vDhG~kmAThE}!RcURAWrVS~wWz7$uljKINUV9hV8 zsFP^WHbrBkjy6IxVP#jPrV`Co;aKLVbOwiPELH4qmo7f>x_IWLv&qViU0 zeIb;9npIX_0Rt5-C7hCdo}&of>ngZ`T3ddYxuFStgH#n9hV+G@BqruSn!Q`jDPGk} zjHwe~>>+#$8xRf_IySN`H5^uQ)nuxdUN@lIKnXhw0J^?{1)8n`1-hPs1)7cm1*w13ikzp7gLmO!J+?D=)IWspXnoKFyB141C-%*qnY+KcC<*o8>+)dbT+ ztSUl8!SPM9=W~HZ=cvX1A$+Ay%&jUa$*HMYHqVLGW|^34M(LzZ&=Dv~t-4@VU=Tv~ zMo3>RY?WfQC@WX6F4j7nKuo<N41V=h4%8aZm`=!XU7A(k| zKFgk(e5o=cch+=(D4ra zG?pXe75_?XM${}L#48FdV({-^oFV;B{g3BcCgsnFx#PgG6)AtrO6(M4lo8y(;4)zZ z4`}ri)0<>3HuT_*S%yG!}Aam@4o9}`&asIG@ISgtubL_FUFuw-;FrN;5=H+?`D2A_M*%SagNCx=NvCFzeQ2@F~=ToKXVx9LFU}|F-O0L znR9Q(9DBAd<~XPDF;78%%wgh3nP=iz9&-rz1aoNY6m#t36!0|&x-v7zragu^EGm|H zENq53EFhjaHo*zZEqD&WJP!J0o{Z;%%opPs6m#q^$1)#*y(06|vA<`IefDJL@i^aS zzCckjn4f_&8|K$xZ_ONsWVy_jzz&$71v_9q19rf?1kbRTCt&Z&d?fVF{A}o*IrYx` z7qA!Rqo9B0co?*TInG;FGlzZ~nB(D46LTx{MbJO<70^HP0_dMP9!l(I zehKu?9ETc*nBzR*Fmu>dC-ZsGKl5Td=kRH15mP3#_I0<0*3OGG8T5X z2pCFG%J@(Bb^$}!N|}}LRsr+2EQxTlfFUfU3>K<%Hwc(jWs?b43mAh_$}$Kq5-?HA zW)jX9@I=D-gfj%prezBVrwAC6NGV%H*ec)*!exZx1e{H{ny?~Zk}g|8_~=h4cp#T> z1K~~qv#YZ8g!c;=$`RfL;}~aD#x!TG>v* z)dH>{+(LMffXQmvON8?U>?FLOaE5@%df6euDFR+ixRbC|zzu|bgyRI5Xz#9n15pEIiX2J=Cw+na+VJqRS0^UkEiEy)kA0(VY zxIw_%2u~(lE#M~zXAoW_;O&HG63!R!GlcUAX9##F;RS?K1iYK@BEnVyw-7EP94Fv5 z!qtQo0aLVPJf`bDdWz%UN4SA-r+_Kyvh{@b3-}=6X2LB3rs&Hy6W%W1!-TgI-YVcu z!rKTp3%HB$cESw;rfSM|60R0-58)QViv&znmAynbU%Do!dnGwC7eXKS-^>eQwTQ*IEnCN!qoyEOE`n@A_1omo=G@gz!M4Q6V4FuWWoyw zrvQfkn?KL@N64VDbuQLvS5I8SbJ;*q>K3Xl4%pq|9Im?3QRFcv`nI4%b|S%9hKPH%&YKOEXIoGlWXVC zYwY1vQtM(I_s6r$)|J}gt>5k4xEfS^ui&4?)++STVcUvoWDkz7s&;nRwvERo;G4%i z?{wIn7>~%j!?t}q;_(jKGmeUqnhx8}W#bj)PlJImG10S;PS^J~B&UkoD{QfKbKJ+B zGgw)WX!iZ^Jw@hech2^@ws-mcFF?{la(83)sD)jQOV1G89ksZhLR`|=My7AL$-c0) z+3OsmcwNqq&xB9*oVyM0>RUJu5Z!hM$*&iPKf`^kAb&@Y{M>%Y zX9L}9YmUe@y1YR2zJa|D`F95QEjugR5bXWniT(!HPITL5l7Czv{>t+ zzeJGVLh`vlj5tW!)}UcsF34{Ql0UOw@-aZieDZDo&hPJ@bxNC#-B;qS+4qY%aDAMp zyAhQlel+?Yh626(kB@G+vGv=sK0J@+b-sDrTfYHLB%=4}ux(&x9X19J$mlZ^Uq1K? z@jt8K5{{ry_dolM{%3>`g3fFFY7Q(g&O|eLy!jZ_%rz!ZgH?ew`KV!@fYBgI$o9H=Xbh_pW4PdS zm=n2l_*Q+x_CK)(I*&!0om>)wOJQAstF1yc7e+rR-XW=nV-3hfW*7rx41L7Y?K#Jcy zuG(TK3>h8tC(CfDOcCRaBrhv!z_F0sLEIZeFic%|Oa(9Xr#w9iTYWonFhUVWAwEKA z9R*GzD+&^0J-LZOo3w6DkiW}L(rj&Y_o=qF7g*kI9;A3}uaQq2^+=hf z!)dnoUj0&xz};eLs+65V8l^8p3sST<46nNYHNN6(;Z~$Qxq4Q^zSY85-_sCrW9x#& zwETmh%}~!^RGz{u-okAiHg4L0aad-ZGUHB9@f1F&7CzWvrlb+|n_VYH)qKH7SS{S@ zwY7O{n>%c6tn0A7Br|Rp70PZam8^);GwtMRiQUf@Y6Ws4bEk_(jcw(Zb!<%8E zHTgzD#B$vUR8#XXvKL9v@66&dfEGl)@e5&h3%o8fJkX1Xd3smq1aL6P$TZ++fEYTQC_jS~%@B>~~HnGH%LPs{5*%hdTiLm31 z{{llVd0lsa=@(Hfe65v8X9Dn*P7nAK;YK~5ENs>MO8^$zsb;Ys`#qRzY|UCkZxc^L zxd*F^-?cZ!6Q^dFF^yx`=lw8axf^RXtXG~-Ts;Y%g(rO12_iq?OwLnx3JVtpwMHA< ze6Xu7gzFXVP8;EikbvUjPQGzZ2bzHu_I(%o?#K{RxFbVO)Qni-3Wm6Ek`fZ_(a6;^ zSuKo_&K-_koo@EMihdhgYd{ptuTp2ns?%fA_SBz;I=Fw&#PyiusVyFq8{IJV>+&^t zrpN5*jPewAanPrrVYnoaxmK+)KidE{JRRRWq|P?GUv|cOY@Ni5P4qQEeZW&~ovxc> z8qlL>y7|aG9n)h(i^48g63+~LPw4beZ*eciP`$3}Fo)UKBG7QXga84h&Dy#r#+Rhp zVlh69()SINfb}0I?pVs;mg-NfOoT;g6wU<&u^#psms%5>cC`L2v1hMO0Q(w!b#)`w zr$%hw(~hqG+EWvo+Hz#CQNIw=CvY5UUX1&|%E2%rxgK9}O>F(wYNmOiYHn^-W3}Bm z_U8e6m?b#U1N6Sf*cw}ZAD~D3 zN`_rAKmNI~nbAIcJS1)0vjojRO4t|K2(>TGu&942ZxJR4lY%|f$NK6;-{*mdWZgn_ z-G$COa)h07CHV6Zj?ToI4xD2^H#ugf6>EW+MQx~sQc_!jtG>4X-=^tqv6v&rr1}D( zL1cdZ1u-?Y-hCtaq3i@dCc%&NUEt@uAU~IbA9cRjeZZ3w<2*-aDYZ9CrOjT~K8>FP zY_u=}Ka5W*1Oumm0awph#3!l?+7`+kq|OK^w~8cY1eCjo;I&Ea1C~4Q#60rO7?pY) zGf2n*6Gwzf=0xv|SRCc}TA@;mY`7W+@yRm(T(hg)ly+; zTbI_}=aDUAL`%I*!fo%d3uxkVash1Iet=t7+gP~<%oqh;jy&w@i1pNW9Xa4>*N}Dr zi8i*FISK`lhX5RTKg2$-gZLX;f4W|`cj5maV&?Plgdu3wM*GzCyYQHAq-g(wXb(>r z!Tl2& z&hW0FTh-!*W9;4*r-Kd>x5aSSt`;HgEOhH?v!=H26qEBLL*wHyv_yp%H|spMV-#gE zs#V;gyCe`Z_;Wme!Xg{%OA<`Jx&Q(Z5k-uvC6?&#Vgh2FMNe4kguZ49e-y_hz?R@U z3UZCD8`-Y@l>2xc{C|nY%eml1Fwz`i3s|nzyjUz)Z>fdxIB9*&n{QUvB&Z1H4tZ>c zQ(N5rHLrPdVpIK?OP;z;;$vB(>xxhGrF|w1KVGnzBiz|Wl(}2#E>ZIigX|R5c1SHe z3~6yE7)P-p(&eIzfsw>oA&gE}hbe7E!fg+vwshYJcR_!PrA62lkUoTCKJu-=E+g(zK%zZzn#B8myRGjSlU zizzst-$j3ot!qFe7=PWwp-)Woy^Sz2IB=u?@nxJqvpqA=45T0ewUK>y+#Z8&d3D@Q z26%Dlj=~YUh`u_qZx=oX-eM|WOsM;!W4c%hd&g(<;mlxuSb!`$qSA-dohIU}y(W)V z;QS`t>ijZ&nDa>b;AZEiO)Ygp+D%GoiG;?_(yveq5aar6TM z?R-wgD>3S?H~{y{YlgYHO=|Y9VmzXN+{pk&x38V6Ff=)GfzkNAe-QpOZ3K-N&19gc zw-x?OvljeaS}A5hW9v{nDpsp8xPchlS$bTRM?3M{B8#0zF~lAW(U(5h*~MMYRQ3wZ ztj4JZ40W%isRn^C49FIH(RaeEFg3Z`h9#{44g}b4PQ!FL1Pk=mm^^xiXKHrYPk-s> zdA_!|ccDi_ao}pb?PI~%bdy>b2f-ehT-rRv_OYeuDWE{$=JfG(w>8v%Y=s}NG(CXA z_0z$CHXz>YHK}4`O)cKp*bFzY-I%)P;6LiRJcWnVXMS+vXp7_9B2R71oSfQ%`Y7f( zR`!MP1}^`Ax&!bWYF$_RbpIGRxiGXN_p(PZ)d<~D+MIqN4koM?_iPwv_hob*QjGy5 zVGjC4Lp)G;*s`PPhZSH0q`(PWozEf!iGA=PQ>MB5Qc!^(e@1f;A7PH5z2?XD=QEfT z(05}`t`*V?dDP@9gP(3}9fp?+5ENQ=#5J58Qa7Bdrw%#4Za8Um{;T06^xklCu=8WD zw+n$}(*ck7;0G9idJ*iW!@VE(5TN3Hz6*CA?@Rbs9@jzsBzk%%QQ@~p8AOLUKPKh( zn+{l-)`LdF$#hH8R&g`l(!_(ehLh7QP0L|hq;y&+B|+cn{G4S7qB=>8Dqb`Ax#hLWoXc36=1SC0Vo~ZCQrH8{yka+2=+f2CbJS z;s`E0LOk6)usq23XT}L_EkGZsF9UCVyoC-!}_w)BK1MUQM zIT+ai2MgYOf5c!o*tL*Ta2T%>66|UMm~Pfb@`NUxCy0_`ZkRmHX%YTe*fGGmZv#E} zUPRY$Rzf@$_Ym^1mV%Qd-QVNkr6yZ}((OZmXRp^amJ!6pHjIJ_TSSXq;}eAu1wnWL+x0rFO29a zuqMN6cZh08Q9A=KAq3Il$Ix-y0gbWKGRGgwc1@ zol8pd1<@|-{F<%>+uhmZUBnU4T(2Y1o#eUjaGI^NZZGy*JPqZxtMKpuzN^8}mddV# zc<<9EMiD!aF*|V<|5H#wMBBX*-N|rE#?zCrno{HsLuieybMl19-7iDv9kx!&;x@#v zogp%V4qlvJSXlVom$=(=;+Gfg_2$lv-t%FU=cVty-1Ge}FM7qhipTN3p+Za8XV^NO zyXYhXVgpYv`~#L-9~))4^HR?G7O%Pin*bRH$5?iZ@Vv9fA7$CG`wABGWa%XK*6ZU3 z!j)Qf+-7op6usvov#0*>9>3YdD$9=e)7BRZ#5#`E?zSk`ve;;sEhgIakwqX4^rrvD zvLijsa}r2VKyrO_rDey4(@7mA(LBBdH@Dr+*maNlK;7VW^Kkjzmv@E9vlkm-Z$^}N zWi$-KI}05%_^|Al>^ZUL1lVkfCLvHTtv8?PoQmMl^;z_u&#)FwM`Kr~WzR|6H@UfYkmAQaHG~ALc@0Rw5dndp(O?>8aHWJhf#@*1?$_*1E-4D-JYeXrXIin zHBWYNKusIQWPmi4ZadU0;^75U?#oa_V{0WI-)g5hc-DdmF%&9DJ+Lj>)8RZF8pbje zIBTIEyfdXa@AFNk{p9U~jqRl_--O3B>e6G|=lk*yU5p#Xy3cZF2UzeF?nnIjil_eI z5u3Dc%Z@yZv(1xtc+dAy7~bIT)%wo$v1cKKYFIrmda84cS`Xdj9oqBRKtmlglV&@( z<`&Bfxlr64>IP2pyu$>e1K=ToCd&@Jy3O)J`oKNkL*~1mV}m`PMHxtBdH-G`-lzxt|eDq1uUf0c363BEDURV2H6~NpYKf*{Jin3M7c9 ztqXW3d5WM7J|hcgwmyyR4bTc0TTYCn>E%uEv9~q4 z+z!5h*|Q!U=;5#HLRM+fm~jd}M$Boz6!XmMI*oV`;-A58_n2V$XWG2Hm*vBQ^ndR@JT%K6Zp(O^q)qg{bTq8aKlBfO1r}}!-11y~XWzkKU1j}2x8L(Tr@p0WJYD5Ie}Evo>QN43BfW*@JPQ)zHhIX&JLc* z=<~(5nS&I{cW=OWJediWrUW+d5>y3VKw8?{lM}(UGz5(-qZI4{xlT?`pdmy711_qE zbTk(QL!dLmM6;^T)8(lfHN7XOUd8v1Mwz2(6SZa&wWxwa0ub=e1 z_TAgwoS%d!y=(lIb@5mVxkr;edpN}}-H_GNv;m|s=R>5l8yyE6P>gifW_5;@vT8=1 z*L6h5iWaBEHqUEvO7gnCLmecDC!T!SLCP|gcXBQWS#G0+7QiP-@01HW^wK9mH*u<1 zz=KOHkCXZIRZeQUB^b=Cm!uR^IfeR_;;(@zrTFLx;L0r%T!WyB0r@#t>6XTVSl?27 zjWKsXiZ8)tG$|qqyb7elrMMg&N06cj`(~rg>pBxsk@07k6tVU___Gp%NMMzeWKdRe z{e#g9d1p~ zF4od?9!Q7FYBoBKAS-dCdM@g`t_uRP!q8x4mk}1bIKZ&AX@qqv{Ey`)Z7ocG@BNMP z^R!#st(=GbN^o?$F2O5~1Gkq1@8UqE1YZELfCRsL!<+e&cP0Fv1(Fjp;MPSvv-NJF zA;_6qK=Ieds-g@W&4{x!9sCy6p{HKHQ(#zncul5SAf(RVdpf>XQQiGlv@c@Pr+ zLw+*e7>|M5T9 zTKF%-|D2Ps%3%E8Dkoq(d6eeUSNso5PC#d*_#bsI_;DHHe_B&8{)g=Fr)!XO@Aw~8 z{l@=oAS9RMzjCo){Ewnw{GW=_2qEoWTAG;I{m1`cJutn);(t~R3fceWU@Aj=X5YcR zRG8cwPA>21IvI$#}f7~P0Qy1Kx^%2=*fg$N17cvU! zwIV;w!ALPyYul&{6dCshzQ`M?l~jOqk=Psf85>008;k}Ay(KwAgzDd79C)!WM3#K1 zSIBZbE5&N7Z5+f#L4BTUxb&c6bD^)%kg%|4u|^Af?stt2MvYEk`b88_$&(CfbED8D)D1_g%A19uZR0c}ll=4z(g>i=g{~K+tUn48>03 zZ{Q$;Y(=2`Th`4;2$AhlUAALUsYT&J!g3EAl&x_!?@N}@fhO~y#r7%HIWJ17av#fcMMCYnVC-yjs4$Lk0rx$!|-1@>&WV`O~EU&iH@wSQ!-Fic1cC!pGX zD`c;AF1qZVir)I!kDY`g>mDg^_&g_YUKIr;cbkIc`hM(lu-V;>fL=S_()VKrSpG(^ zT;GrFV)?V&C0uLRCB$>EVY`G45q1f?!5#NmSQORgg(!GxF;!$=Kx2AQp&CdhI9HbBPEX7390Xl!E*wVjMk-{q<2fGfqjfkA$+W#MyzV^}>SE=1Z#b!k7l6Au2HV<3uSs_xqFfhwXgxl?(Z z))CmL{D{GDr(#2?@%cn9jG?jhD?Ige^`wJg&3KLP^oaT61tUVRP5j|^=rPu77bV-Y<~7Ga^EO$fulz`vd+S*l+!n-0|<>f<5tsQAU&R zu(hqvu6BxQeW1IjtHLhP6_1X?ySllru7rRq`tK?)q^qk9U5U4n!baua(Z{I76gKtW z)kh>AP+u2Sp^b`fH-wLBLtkBqZT2S6^3I6Y#T%}xTSZrW%6CBsC)XP|Nr=G7kiIw( z!E0>)UHwa1oMy9M3ROu}j*8ILeShggz9KxjU(o7vRJVt8)nw?(8lkI+eRU;HA}4_s zC(Q4G1qaoZE}nVeRf`ahVfq4C+)S=}Mt{@ep!U8@F2sWQKZf%kf4|-L{6`0J{+Dxu zfj7S5@uu=YI)ZR7;Jcqg3K-A>R7+kLU%wl~@fl~|wcv-%F@;0tKg#=_|3YGs#fw<* z{E*%+kiC24pG!*@VC3Mfr`c1RZlD2Aqs@O|Qhj!{lhuKN?h={`ng8PNhB-L8#hcj` zMApmI$oUUi)Z{^6QIqmd$?*<5j*vC=={kiFeb4_nph@}uR^WXy!yifeDj|!;*3&Nl z1N{5I7`$NSt!wKri}!E%Qr!t_%~x)JyR9v`-S#)Uz06k~xvRVrT!`OZct~nSyi1CR zTf8v(75WbTowJoqU|eMW9n>(t5BkGvr*pI)Uck{hF*N>tCedF1;e~rR609lwOCIet z?7Dd&uQY1=ogN-Sg`Lsu_!Fgdq>azLc1Nh+gnCR7{JqZozLPu*3;uou&*xH){xiG_=bHv4G`4Dph>pvaQ~Q2bf5d@?Ox)CzsSYB!9iv9$;s@DF|P za+TrbT45(zoVhV4Qtv6dY8$=y-GDbg+kH=f?*7xkT?LKD?g~pOP%AIaH!lp5Qp19Dj^SHa2r z{%vu5N3IN|LB*4U;ov~J-!^G-;XfeZTg^d1^NGL&MUU+u9*?Sd2i3W87wt)V#nSW~ z8sZP|j$$ZcG0jSCP~sb^_?PdiGV>JfBgssV#+#$~d%PHKwkH78-{3xu z#&|Cj;84|enBwbVNnICS>mEui1OEU^@aN{5OAEZmGa0Nvdm*mj(?4?m)QR!qOefd` z=Of?+$`UJu?rl6I48B^N*Lz(p8nw{DZ2~hydkgPzIx}&*KoMQ6#@6B_Mz*e%InK zevkog8Dm&NzSF_8num8=`FDx|H-n{9n0+>AQ7P#dJl?!@Ug&j={6Y@kWl$A^C0T8- z-IH;O!N(G8vx1Z*2g87iP6A9YutUHNW?P>?4PL}AjFa_oViegpUj{=3ICmi`e&hq} z`(_A&v2+r)LtdBoVI`K^Q4Vw6>%4{z3adX}kCqCQvrT)pKUpeJdzU@UcF5A?!HIy^ zmGYGw(RTp^u2|g_sKj*gx{gt0Fi!NPnK8NYZF`*K+Xs47V)s;_Yj4wwzxSW#y9vT; zY>mdx#`;EqbfA*&yNcf%oGK7LItS+GDuCo%C;ZNl-luu1*{$mfvwy!j5EXUD^xp|I z{7&mOH1%abxYyw~S*Zv83j3x<=qFL8Sj#KL2Pv#YHB0cRfJ*0Rwu{^bU%u!IzxOvX zti4gK0lrya zb*ymWYcJ(hmDciFYh{(w>MV0$nD|VIH9ITET3S`JtjL)hHb(sy-nDO&OtJFk(8E4T zV&#vRJ4$-VC%moBX;F2xy}V?sRpvU6p|TBc8|aq|>)#tmx+vK7&+)w&pD>s-5oGbP z1FhBQpKBAwM6kQCpNzMPADSPnB=aLVw=TX!G1kL60`<68f-00^8=~0w*&3-={7Syi zp3oRR2;(e+cy73$cHvknKk+e@w?mXOw#3AbI9D6sAn!w;}>P8b9h_ zXl=yTzrY|r(O^U(kCLX2L&$(}o3Oa;;{byfJcsJg0F z34YK4pGBBrHGDmRpI86|dLZ~8<3*4C|I0NEj2n5q67WPM{H(V!2?`@!#98_x}iw1NW+kZBjJ?^ z@m+w^kdHt*9f`l^dIr*&NM|7>AdN%{?^lPzMd1@h_2Ek+>k8hlHJp z_=Yt0l;S(i7a~tWx(ErUh~gW?JenPcl#DbUDFq3C*eJdgdnt0gzyHnuR|2{OGN)%{ z+j3^ioHct+Zr)W_=U+2-UP0mfYZqL1ebM6L5=ZHhvhtgkRxGQms=fuEp{ZMb>xz}D zQc@>eI`OhemrqW+WV|vaE7hzX zH;pdXfP~M;;3IXxf}{&d=(>dO5??nPH!W*cwg@POD03Vu6@0XY-;qJgqv-XvIa+;Y z#gZy~wytcMUKK>nb2!VYN;JHJs-^hET^?dBe49pZ_FMwTU9ANk;OEJ(g8w^s)%d!e z<7fJ_FQ4%9w15=o_UHJMxUy>{!gm1s+T$d1os57VabFV_eD~fqVFB!g)0Z8IeuXd4 zzp^O$q|G6EmLFK8g=kxpWNTGvDL!&#t;I(*twnG`_=+KRPtICd0!(h8YViRtZrl3d z1M^d-r8Qd4?;N64FWv*&Bh6nXTZvK)&m!lBwi{re)~juGMG?dQ6;6pNzQ?J#)?_PU zm|sL+!E;W=LeAg${ReSxzTfXZfxPJoH5nO@10Qpwr&meC>o`?r8M_G((E$A14z=AVHN%=h{I{7$oyIXq^DJ8IZ~ zT-SiL=5^6gPY-F$Y|re-{2Peo3{{9SsMLA2KpEb z>F-C{@UY*{Ulj`A7p#k(wbtw!5OwE}VdjqZ*37>RH)l$G2H=UXO@8N>_|wUMmZTqj zn#s^X&QQ|lS1qz(yZjDz0ACw#^avw<_E5@i5%A)1P6g2i`4Iw<@@+u9xsQ4)nrub= zvB&&=?ll7aWxArPFbGIh#O7_li31JpNdh=IF7q{OqZbS_%i)rj9^fSbk1@HDtBtip zkP)(rg$!n*{t)YRSMagtABn{t4jM8Sx>DLN>W6v_T?pDo7vm{Q?a? zo3frWgbd6aIt%~)P3~zn0M7(UCeC7l4@nEN$`x!(dDK9lQD zx3nw%t-uq&n@3vu+>go@1~0}BQ|dweV%F<6mAy6^zj-GdP1evw?U|A_u`Wyo{#dM~ zqcwant{de1VSfuypN@K-3y_{z7c^hP@vK07F6xg!uYvwFxkPU=`q8YRw;2RO`$>X5 zD_F1jEp&4s{?Yl>{cu)j`y`$HOPoUc9v zaA62V^lMQwgSG%qNc?QzXJDQ0G~#0{HxmD zL)m5v+KfU>@-4<-9vz|0n%->~Z~6B5{rAP9%~?O+hO%r%%v10#ex3zwd+~K3+A!Em zu^zWDMtaZhe=o~2b$)NCahSE;0jJZDW`)|j6 zfS+teH+fhG7KHF~mBCKg7vr^rPQRbON)c$Q%Xn)jZ@EBWT(|Q>zkeO=Ti1y`Ck7kw zXAUjXdghe04UKXdK$@Aj{C?9JWpjQqDSJ!Ja6QDBj;2h03KMJ->i`5r6-W{{P+~|bRw;k=c)sdUl`s9Fw8UJ^`Dm0^qOH; z%pcHleutKD3v!+%e}g<0c|IPL4nuyT7V{N(0+7D_$zRnBfC|_TWVlhq3dh2Db_xEW zt;HeHWS_W8o@Fn>RF4PDvuU0~AH^Xv?>lke%(H5KneKGt921_jR;8dEa;zeaqsS-Y z(E22D_Vxeb+SVMTvI%2+7-R1Gm*w1O+v~+nvYb9v>a(I(k7&b zk#-=pBfX9EDbjJIfmXCf8iOgJ*e56vO20J>k&Yt`JRj|m#vn~X%0cqot%$4tk45wQ)X61|#dS-F+?BZK5+%8|3pOKWg~VlOK}OC179d^6jzqS#UGw1c?{ zhmu_Etg5L612Vh080aJ+dczY}_E@y6yckXK#EbtVi>_ri_@=gC(=J9|QC_)J%In|x zmvd(jQWVlLEhQq?FU~<;P>q;>#N(V~S`jVhDC>#G1QS+{W8M&tb5m=td>2dBd9ml=iFUy&1NSyDy=bUHS zj(hgYesuf-+`}b_HuM=x^ci|RbNY^j20Z#0rbQsmdX7)WE5$u|r9YvMW8&EKOQ&0e z0v)dbI82OT^ouefSb?PDxin~KaYDI&k7u-^+eDvtCqiloVq1F z`g$fG?rB%NNRRx!iKNrx_rRIL^+DW220X55OzCW>UBqGf5J{&;KgkqHE}sF9<>c=u iaF` 1000 -#pragma once -#endif // _MSC_VER > 1000 - -//#include "Shp.h" -#include "InkaTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -class CPointerArray -{ -protected: - LPVOID* m_ppData; - int m_nMaxSize; - int m_nNumOfData; - -public: - CPointerArray(); - virtual ~CPointerArray(); - - int Add( LPVOID pData ); - int Remove( int nIndex ); - LPVOID Get( int nIndex ); - inline int GetCount() { return m_nNumOfData; } - inline void RemoveAll() { m_nNumOfData = 0; } -}; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif // !defined(AFX_CPOINTERARRAY_H__AB67E4BE_A233_4E3E_B257_9830D90326EE__INCLUDED_) -#endif /* __CPOINTERARRAY_H__ */ diff --git a/src/commons/drm/CXMLAttribute.h b/src/commons/drm/CXMLAttribute.h deleted file mode 100755 index dda8fe3..0000000 --- a/src/commons/drm/CXMLAttribute.h +++ /dev/null @@ -1,37 +0,0 @@ - -/******************************************************************************** -* Copyright ? 2004-2009 by INKA Entworks, Inc (www.inka.co.kr). * -* All rights reserved. * -* * -* No parts of this source code may be in any way copied, reproduced, modified * -* or distributed without the prior written consent of INKA Entworks, Inc. * -* CXMLAttribute.h: interface for the CXMLAttribute class. * -*********************************************************************************/ -//#include "Shp.h" -#include "InkaTypes.h" - -#if !defined(AFX_CXMLATTRIBUTE_H__2B925786_3613_47B0_B85D_CAF2053F46DB__INCLUDED_) -#define AFX_CXMLATTRIBUTE_H__2B925786_3613_47B0_B85D_CAF2053F46DB__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -class CXMLAttribute -{ -protected: - LPTSTR m_pszName; - LPTSTR m_pszValue; - -public: - CXMLAttribute(); - virtual ~CXMLAttribute(); - - int SetName( LPCTSTR pszName ); - int SetValue( LPCTSTR pszValue ); - - inline LPCTSTR GetName() { return m_pszName; } - inline LPCTSTR GetValue() { return m_pszValue; } -}; - -#endif // !defined(AFX_CXMLATTRIBUTE_H__2B925786_3613_47B0_B85D_CAF2053F46DB__INCLUDED_) diff --git a/src/commons/drm/CXMLElement.h b/src/commons/drm/CXMLElement.h deleted file mode 100755 index eb74a0c..0000000 --- a/src/commons/drm/CXMLElement.h +++ /dev/null @@ -1,57 +0,0 @@ - -/******************************************************************************** -* Copyright ? 2004-2009 by INKA Entworks, Inc (www.inka.co.kr). * -* All rights reserved. * -* * -* No parts of this source code may be in any way copied, reproduced, modified * -* or distributed without the prior written consent of INKA Entworks, Inc. * -* CXMLElement.h: interface for the CXMLElement class. * -*********************************************************************************/ - -#if !defined(AFX_CXMLELEMENT_H__B6A6A39B_1980_4A4F_B68B_E87B53A3EE9B__INCLUDED_) -#define AFX_CXMLELEMENT_H__B6A6A39B_1980_4A4F_B68B_E87B53A3EE9B__INCLUDED_ - -//#include "Shp.h" -#include "InkaTypes.h" -#include "CXMLAttribute.h" -#include "CPointerArray.h" - - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -class CXMLElement -{ -protected: - LPTSTR m_pszName; - LPTSTR m_pszValue; - - CPointerArray m_pChilds; - CPointerArray m_pAttributes; - - int _SearchNodes( CPointerArray* ppaChildNodes, CXMLElement* pCurrent, LPCTSTR pszTagName, va_list args ); - -public: - CXMLElement(); - virtual ~CXMLElement(); - - int SetName( LPCTSTR pszName ); - int SetValue( LPCTSTR pszValue ); - int AddAttribute( LPCTSTR pszName, LPCTSTR pszValue ); - - inline LPCTSTR GetName() { return m_pszName; } - inline LPCTSTR GetValue() { return m_pszValue; } - - int AddChild( CXMLElement* pChild ); - LPCTSTR GetAttribute( LPCTSTR pszName ); - - inline int GetChildCount() { return m_pChilds.GetCount(); } - inline int GetAttributeCount() { return m_pAttributes.GetCount(); } - inline CXMLElement* GetChild( int nIndex ) { return (CXMLElement*)m_pChilds.Get( nIndex ); } - inline CXMLAttribute* GetAttribute( int nIndex ) { return (CXMLAttribute*)m_pAttributes.Get( nIndex ); } - - int Find( CPointerArray* pSearchedChild, LPCTSTR pszChildName, ... ); -}; - -#endif // !defined(AFX_CXMLELEMENT_H__B6A6A39B_1980_4A4F_B68B_E87B53A3EE9B__INCLUDED_) diff --git a/src/commons/drm/CXMLFile.h b/src/commons/drm/CXMLFile.h deleted file mode 100755 index 0a3a2e2..0000000 --- a/src/commons/drm/CXMLFile.h +++ /dev/null @@ -1,54 +0,0 @@ - -/******************************************************************************** -* Copyright ? 2004-2009 by INKA Entworks, Inc (www.inka.co.kr). * -* All rights reserved. * -* * -* No parts of this source code may be in any way copied, reproduced, modified * -* or distributed without the prior written consent of INKA Entworks, Inc. * -* CXMLFile.h: interface for the CXMLFile class. * -*********************************************************************************/ - -#if !defined(AFX_CXMLFILE_H__21F76587_B9C8_4407_9C16_186F3D47ADE1__INCLUDED_) -#define AFX_CXMLFILE_H__21F76587_B9C8_4407_9C16_186F3D47ADE1__INCLUDED_ - -//#include "Shp.h" -#include "InkaTypes.h" -#include "CXMLElement.h" - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - -#ifndef IN - #define IN -#endif - -#ifndef OUT - #define OUT -#endif - -#define ELEMENT_QUEUE_MAX 2048 -class CXMLFile -{ -protected: - LPCTSTR m_pszXML; - CXMLElement* m_paElementQueue[ ELEMENT_QUEUE_MAX ]; - int m_nQueueIndex; - CXMLElement* m_pRoot; - - int _Parse(); - int _GetElementName( LPTSTR pszElementName ); - CXMLElement* _Pop(); - int _Push( CXMLElement* p ); - int _GetAttributeNameAndValue( LPTSTR pszName, LPTSTR pszValue ); - -public: - CXMLFile(); - virtual ~CXMLFile(); - - int LoadFromStream( LPCTSTR pszXML ); - int LoadFromFile( LPCTSTR pszFileName ); - inline CXMLElement* GetRoot() { return m_pRoot; } -}; - -#endif // !defined(AFX_CXMLFILE_H__21F76587_B9C8_4407_9C16_186F3D47ADE1__INCLUDED_) diff --git a/src/commons/drm/InkaTypes.h b/src/commons/drm/InkaTypes.h deleted file mode 100755 index d7a9291..0000000 --- a/src/commons/drm/InkaTypes.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SHP - * Copyright (c) 2000-2007 UMTS Software Lab, Mobile Communication Division, - * Telecommunication Network Business, Samsung Electronics, Inc. - * All rights reserved. - * - * This software is the confidential and proprietary information - * of Samsung Electronics, Inc. ("Confidential Information"). You - * shall not disclose such Confidential Information and shall use - * it only in accordance with the terms of the license agreement - * you entered into with Samsung Electronics. - */ - -/** - * @file InkaTypes.h - * @brief This file includes definitions of constants, - * enumerations, and datastructures for the Inka DRM service. -# @author Jihyun Lee(ezhyun.lee@samsung.com) -# @author Donghyun Yoo(marku.yoo@samsung.com) - * @version 1.0 - */ - -#ifndef INKA_DRM_TYPES_H -#define INKA_DRM_TYPES_H - -//#include "shp.h" -//#include "FileMgr.h" -#include -#include - -#define _T -#define IF_ERROR_GOTO( error ) if( FAILED( HRESULT_FROM_WIN32( error ) ) ) { nResult = ERRORMSG( error, NULL ); goto finish; } -#define IF_TRUE_GOTO( cond, error ) if( cond ) { nResult = -1; goto finish; } - -#if defined(_WIN32) || defined(_WIN64) - #define snprintf _snprintf - #define vsnprintf _vsnprintf - #define strcasecmp _stricmp - #define strncasecmp _strnicmp -#endif - -#ifndef _SHP_SIMUL -typedef void* LPVOID; -typedef const char* LPCTSTR; -typedef unsigned char* LPBYTE; -typedef char TCHAR; -typedef char* LPTSTR; -typedef LPTSTR LPSTR; -typedef LPCTSTR LPCTSTR; -typedef LPCTSTR LPCSTR; - -#define DWORD unsigned long -#define LPBYTE unsigned char* -#define BYTE unsigned char -#define UINT unsigned int -#define ULONG unsigned long -#define INT32 long -#define INT64 long long -#define TRUE 1 -#define FALSE 0 - - -typedef char CHAR; -typedef bool BOOL; - - -//typedef HFile HANDLE; -#define ERROR_INVALID_DATA 13L -#define ERROR_INSUFFICIENT_BUFFER 122L // dderror -//#define CopyMemory AcMemcpy -#define INVALID_HOBJ NULL - -#endif - - -#endif //INKA_DRM_TYPES_H diff --git a/src/commons/drm/IntelDrm_Core.h b/src/commons/drm/IntelDrm_Core.h deleted file mode 100755 index b8b4b48..0000000 --- a/src/commons/drm/IntelDrm_Core.h +++ /dev/null @@ -1,46 +0,0 @@ -//typedef char CHAR; -//typedef bool BOOL; - -typedef struct t_cek -{ - char *CID; // Content ID ¹öÆÛ Æ÷ÀÎÅÍ - char *CEK; // Content Encryption Key ¹öÆÛ Æ÷ÀÎÅÍ - char *EncryptionMethod; // CEK ¾Ë°í¸®Áò -}T_CEK; - -typedef struct t_dro -{ - char *CID; // Content ID ¹öÆÛ Æ÷ÀÎÅÍ - char *deviceId; // »ç¿ëÀÚ ½Äº° ¹ÙÀεù. IMEI, MIN °ª ¹ÙÀεù Á¦¾î - char *digestValue; // »ç¿ëÀÚ ½Äº° ¹ÙÀεù. IMEI, MIN °ª ¹ÙÀεù Á¦¾î - char *signedValue; // »ç¿ëÀÚ ½Äº° ¹ÙÀεù. IMEI, MIN °ª ¹ÙÀεù Á¦¾î - char *cert; // »ç¿ëÀÚ ½Äº° ¹ÙÀεù. IMEI, MIN °ª ¹ÙÀεù Á¦¾î - int Count; // »ç¿ë ȸ¼ö - char *CreatedTimestamp; // »ç¿ë °¡´É ½ÃÀÛ ÀϽà ¹öÆÛ Æ÷ÀÎÅÍ. GMT Ç¥±â - char *ExpiredTimeStamp; // »ç¿ë °¡´É ¸¸±â ÀϽà ¹öÆÛ Æ÷ÀÎÅÍ. GMT Ç¥±â - char *ExpirationDate; // ÃÖÃÊ »ç¿ë ÀÌÈÄ »ç¿ë °¡´É ½Ã°£. ½Ã°£ ´ÜÀ§ -}T_DRO; - -typedef struct t_dcf_file_header -{ - unsigned char Version; - unsigned char ContentTypeLen; - unsigned char ContentURILen; - char *ContentType; - char *ContentURI; - unsigned int HeadersLen; - unsigned int DataLen; - char *Headers; - unsigned int DataOffset; -}T_DCF_FILE_HEADER; - -// DRO Value size -#define APPID_SIZE 16 -#define CEK_SIZE 512 -#define ENCRYPTION_METHOD_SIZE 512 -#define DEVICEID_SIZE 256 -#define TIMESTAMP_SIZE 256 -#define DIGESTVALUE_SIZE 256 -#define SIGNATUREVALUE_SIZE 1024 -#define CERT_SIZE 1024 * 4 -#define AES_BLOCK_SIZE 16 diff --git a/src/commons/drm/drm-intel-crypto-util.h b/src/commons/drm/drm-intel-crypto-util.h deleted file mode 100755 index eacb1e5..0000000 --- a/src/commons/drm/drm-intel-crypto-util.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "InkaTypes.h" -//#include "IntelDrm_Core.h" - -#include "stdlib.h" -#include "string.h" -#include "stdio.h" - -#define AES_BLOCK_SIZE 16 - -LPSTR Base64Encode(LPBYTE pbData, int nLength); -LPBYTE Base64Decode(LPCSTR pszString, int* pnLength); - -int decrypt_block(unsigned char *iv, unsigned char *cipherText, int cipherTextLen, unsigned char *cek, int cekLen, unsigned char *plainText); diff --git a/src/commons/drm/drm-intel-util.h b/src/commons/drm/drm-intel-util.h deleted file mode 100755 index 08bb2cd..0000000 --- a/src/commons/drm/drm-intel-util.h +++ /dev/null @@ -1,69 +0,0 @@ -#include "CPointerArray.h" -#include "CXMLAttribute.h" -#include "CXMLElement.h" -#include "CXMLFile.h" -#include "InkaTypes.h" -#include "IntelDrm_Core.h" -#include "drm-intel-crypto-util.h" - -#include "stdlib.h" -#include "string.h" -#include "stdio.h" - -/** - * An application can parse CEK XML Foramt. - * - * @param[in] pszXML Data String of the CEK information - * @param[out] t_cek parsing result to be saved - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int parse_intel_cek(const char* pszXML, T_CEK* t_cek); - -/** - * An application can parse DRO XML Foramt. - * - * @param[in] pszXML Data String of the DRO information - * @param[out] t_cek parsing result to be saved - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int parse_intel_dro(const char* pszXML, T_DRO* t_RO); - -int parse_intel_dro2(const char* pszXML, T_DRO* t_RO); - -/** - * An application can parse stored dro. - * - * @param[in] pFilepath file path of the internal dro - * @param[out] t_ro parsing result to be saved - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int get_internal_dro(char *pFilepath, T_DRO* t_ro); - -/** - * An application can parse stored cek. - * - * @param[in] pFilepath file path of the internal cek - * @param[out] t_cek parsing result to be saved - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int get_internal_cek(char *pFilepath, T_CEK* t_cek); - -int delete_internal_cek(char *pAppId); - -int get_dcf_header_info(char *pFilePath, T_DCF_FILE_HEADER *pTdcfHeader); - -bool get_Uintvar(unsigned int *nValue, FILE *pFile); - -int decrypt_package(char *pDcfPath, char *pDecryptedFilePath, unsigned char *pCEK, int cekLen, T_DCF_FILE_HEADER *t_dcf_header); diff --git a/src/commons/drm/drm-oem-intel.h b/src/commons/drm/drm-oem-intel.h deleted file mode 100755 index 80a9bb2..0000000 --- a/src/commons/drm/drm-oem-intel.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * drm-intel - * - * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Sunggun Jung - * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/** -* @internal -* @defgroup DRM-INTEL drm-intel -* @{ -*/ -#include "drm-intel-util.h" -//#include "drm-intel-crypto-util.h" - -#include -#include -#include - -/** - * An application can install Intel DRM license(DRO). - * - * @param[in] pDroXML Data String of the Rights Request - * @param[in] droBufLen pDroXML Length - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int drm_oem_intel_install_license(char *pDroXML, int droBufLen); - -/** - * An application can uninstall Intel DRM license(DRO). - * - * @param[in] pAppId App-id of the rigths which want to un-install - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int drm_oem_intel_uninstall_license(char *pAppId); - -/** - * An application can install CEK(Contents Encryption Key). - * - * @param[in] pCekXML Data String of the Rights Request - * @param[in] cekBufLen pDroXML Length - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int drm_oem_intel_install_cek(char *pCekXML, int cekBufLen); - -/** - * An application can get decrypted contents(Apps) which is encrypted - * - * @param[in] pDcfPath Intel DRM Package File Path - * @param[in] pDecryptedFile Decrypted File Path - * @return This function returns 1 on success or 0 on failure. - * @remarks - * @see - * @since - */ -int drm_oem_intel_decrypt_package(char *pDcfPath, char *pDecryptedFile); - -/** - * An application can get informations of rights (DRO). - * - * @param[in] pAppId App-id of the rights which want to know - * @param[out] pDro The rights information about the app-id - * @return This function can return any of the following codes - * DRM_INTEL_SUCCESS = 0 0) { + m_name = attribute.value; + } + } + } + + virtual void Accept(const Element& /*element*/) + { + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Verify() + { + if (m_name.IsNull()) { + LogWarning("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 LiveboxParser : public ElementParser +{ + public: + + struct BoxLabelParser : public ElementParser + { + 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) + { + if (element.ns == + ConfigurationNamespace::TizenWebAppNamespaceName) + { + m_properNamespace = true; + } + } + + virtual void Accept(const Text& text) + { + if(m_properNamespace) + m_label = text.value; + } + + virtual void Verify() + { + m_data.m_label = m_label; + } + + BoxLabelParser(ConfigParserData::LiveboxInfo& data) : + ElementParser(), + m_properNamespace(false), + m_data(data) + { + } + + private: + 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; + } + + 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() + { + 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; + } + + virtual void Accept(const XmlAttribute& attribute) + { + if(m_properNamespace) { + if (attribute.name == L"preview") { + m_preview = 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() + { + std::pair boxSize; + boxSize.first = m_size; + boxSize.second = m_preview; + m_data.m_boxSize.push_back(boxSize); + } + + explicit BoxSizeParser(ConfigParserData::LiveboxInfo::BoxContentInfo& data) : + ElementParser(), + m_data(data) + { + } + + private: + DPL::String m_size; + DPL::String m_preview; + 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; + } + + 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; + } + } + } + + virtual void Accept(const Element& element) + { + if (element.ns == + ConfigurationNamespace::TizenWebAppNamespaceName) + { + m_properNamespace = true; + } + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Verify() + { + m_data.m_pdSrc = m_src; + m_data.m_pdWidth = m_width; + m_data.m_pdHeight = m_height; + } + + explicit PdParser(ConfigParserData::LiveboxInfo::BoxContentInfo& data) : + ElementParser(), + m_properNamespace(false), + m_data(data) + { + } + + private: + DPL::String m_src; + DPL::String m_width; + DPL::String m_height; + + 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, &LiveboxParser::BoxContentParser::OnBoxSizeElement); + } else if (name == L"pd") { + return DPL::MakeDelegate(this, &LiveboxParser::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; + } + } + + virtual void Accept(const Element& element) + { + if (element.ns == + ConfigurationNamespace::TizenWebAppNamespaceName) + { + m_properNamespace = true; + } + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Verify() + { + 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: + DPL::String m_src; + 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, &LiveboxParser::OnBoxLabelElement); + } else if (name == L"box-icon") { + return DPL::MakeDelegate(this, &LiveboxParser::OnBoxIconElement); + } else if (name == L"box-content") { + return DPL::MakeDelegate(this, &LiveboxParser::OnBoxContentElement); + } else { + return &IgnoringParser::Create; + } + } + + 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; + } + } + } + + virtual void Accept(const Element& element) + { + if (element.ns == + ConfigurationNamespace::TizenWebAppNamespaceName) + { + m_properNamespace = true; + } + } + + virtual void Accept(const Text& /*text*/) + { + } + + virtual void Verify() + { + 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_data.m_livebox.push_back(m_livebox); + } + + explicit LiveboxParser(ConfigParserData& data) : + ElementParser(), + m_data(data), + m_properNamespace(false) + { + m_livebox = ConfigParserData::LiveboxInfo(); + } + + ElementParserPtr OnBoxLabelElement() + { + return ElementParserPtr(new BoxLabelParser(m_livebox)); + } + + ElementParserPtr OnBoxIconElement() + { + return ElementParserPtr(new BoxIconParser(m_livebox)); + } + + ElementParserPtr OnBoxContentElement() + { + return ElementParserPtr(new BoxContentParser(m_livebox)); + } + + private: + ConfigParserData& m_data; + ConfigParserData::LiveboxInfo m_livebox; + DPL::String m_liveboxId; + DPL::String m_primary; + DPL::String m_autoLaunch; + DPL::String m_updatePeriod; + bool m_properNamespace; + +}; + ElementParser::ActionFunc WidgetParser::GetElementParser(const DPL::String& /*ns*/, const DPL::String& name) { @@ -1412,14 +1852,21 @@ WidgetParser::WidgetParser(ConfigParserData& data) : DPL::MakeDelegate(this, &WidgetParser::OnFeatureElement); m_map[L"preference"] = DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement); - m_map[L"flash"] = DPL::MakeDelegate(this, &WidgetParser::OnFlashElement); m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement); m_map[L"setting"] = DPL::MakeDelegate(this, &WidgetParser::OnSettingElement); - m_map[L"appservice"] = DPL::MakeDelegate(this, &WidgetParser::OnServiceElement); + // TODO: appservice will be removed + m_map[L"appservice"] = DPL::MakeDelegate(this, &WidgetParser::OnAppControlElement); 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"appcontrol"] = DPL::MakeDelegate(this, + &WidgetParser::OnAppControlElement); + m_map[L"category"] = DPL::MakeDelegate(this, + &WidgetParser::OnCategoryElement); + m_map[L"livebox"] = DPL::MakeDelegate(this, &WidgetParser::OnLiveboxElement); + } ElementParserPtr WidgetParser::OnNameElement() @@ -1467,11 +1914,6 @@ ElementParserPtr WidgetParser::OnPreferenceElement() return ElementParserPtr(new PreferenceParser(m_data)); } -ElementParserPtr WidgetParser::OnFlashElement() -{ - return ElementParserPtr(new FlashParser(m_data)); -} - ElementParserPtr WidgetParser::OnLinkElement() { return ElementParserPtr(new LinkParser(m_data)); @@ -1482,11 +1924,6 @@ ElementParserPtr WidgetParser::OnSettingElement() return ElementParserPtr(new SettingParser(m_data)); } -ElementParserPtr WidgetParser::OnServiceElement() -{ - return ElementParserPtr(new ServiceParser(m_data)); -} - ElementParserPtr WidgetParser::OnApplicationElement() { return ElementParserPtr(new ApplicationParser(m_data)); @@ -1502,6 +1939,26 @@ 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::OnLiveboxElement() +{ + return ElementParserPtr(new LiveboxParser(m_data)); +} + void WidgetParser::Accept(const Element& element) { if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName && diff --git a/src/configuration_parser/widget_parser.h b/src/configuration_parser/widget_parser.h index 6ea2ffb..7670388 100755 --- a/src/configuration_parser/widget_parser.h +++ b/src/configuration_parser/widget_parser.h @@ -73,13 +73,15 @@ class WidgetParser : public ElementParser ElementParserPtr OnFeatureElement(); ElementParserPtr OnPreferenceElement(); ElementParserPtr OnAccessElement(); - ElementParserPtr OnFlashElement(); ElementParserPtr OnLinkElement(); ElementParserPtr OnSettingElement(); - ElementParserPtr OnServiceElement(); ElementParserPtr OnApplicationElement(); ElementParserPtr OnSplashElement(); ElementParserPtr OnBackgroundElement(); + ElementParserPtr OnPrivilegeElement(); + ElementParserPtr OnAppControlElement(); + ElementParserPtr OnCategoryElement(); + ElementParserPtr OnLiveboxElement(); virtual ActionFunc GetElementParser(const DPL::String& ns, const DPL::String& name); diff --git a/src/jobs/widget_install/ace_registration.cpp b/src/jobs/widget_install/ace_registration.cpp new file mode 100644 index 0000000..00165f1 --- /dev/null +++ b/src/jobs/widget_install/ace_registration.cpp @@ -0,0 +1,139 @@ +/* + * 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 +#include +#include +#include + +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) +{ + LogDebug("Updating Ace database"); + struct widget_info wi; + DPL::OptionalString os; + + switch(widgetConfig.webAppType.appType) + { + case WrtDB::APP_TYPE_WAC20: + wi.type = WAC20; + break; + case WrtDB::APP_TYPE_TIZENWEBAPP: + wi.type = Tizen; + break; + default: + LogError("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()); + LogDebug("Basic data converted. Certificates begin."); + + //one more element for NULL termination + LogDebug("Found: " << certList.size() << " certificates"); + 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 : + LogDebug("Unknown owner type of cert"); + certData[i]->owner = UNKNOWN; + } + switch (it->type) { + case WrtDB::WidgetCertificateData::ENDENTITY : + certData[i]->type = ENDENTITY; + break; + case WrtDB::WidgetCertificateData::ROOT : + certData[i]->type = ROOT; + break; + default : + LogError("Unknown type of cert"); + certData[i]->type = ENDENTITY; + } + 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; + } + + LogDebug("Registerign widget in ace"); + ace_return_t retval = ACE_ACE_UNKNOWN_ERROR; + retval = ace_register_widget( + static_cast(widgetHandle), &wi, certData); + + //clean up - WidgetInfo + free(wi.author); + free(wi.id); + free(wi.shareHerf); + free(wi.version); + + //free cert list + i = 0; + while (certData[i] != NULL) { + free(certData[i]->common_name); + free(certData[i]->md5_fp); + free(certData[i]->sha1_fp); + delete certData[i]; + ++i; + } + delete[] certData; + return retval == ACE_OK; +} +} diff --git a/src/jobs/widget_install/ace_registration.h b/src/jobs/widget_install/ace_registration.h new file mode 100644 index 0000000..2f4a3b0 --- /dev/null +++ b/src/jobs/widget_install/ace_registration.h @@ -0,0 +1,36 @@ +/* + * 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 + +namespace AceApi { + +bool registerAceWidget(const WrtDB::DbWidgetHandle& widgetHandle, + const WrtDB::WidgetRegisterInfo& widgetConfig, + const WrtDB::WidgetCertificateDataList& certList); + +} + +#endif /* WRT_SRC_INSTALLER_CORE_ACE_REGISTRATION_H_ */ + diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index 5fd9f80..ad57eb7 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -21,6 +21,12 @@ * @brief Implementation file for main installer task */ #include +#include +#include +#include +#include +#include +#include #include #include @@ -30,9 +36,20 @@ #include #include #include -#include #include #include +#include +#include +#include +#include // TODO remove +#include + +#include +#include +#include +//#include +#include //temporary code + #include "root_parser.h" #include "widget_parser.h" #include "parser_runner.h" @@ -43,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -54,25 +70,12 @@ #include #include #include + #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include // TODO remove -#include -#include -#include -#include -#include -#include //temporary code +#include using namespace WrtDB; @@ -83,10 +86,13 @@ const char * const WITH_OSP_XML = "res/wgt/config.xml"; //allowed: a-z, A-Z, 0-9 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}$"; -const int MAX_TIZENID_LENGTH = 10; static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption"; static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable"; +const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = + L"install-location-type"; +const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = + L"prefer-external"; class InstallerTaskFail : public DPL::TaskDecl @@ -127,6 +133,22 @@ bool hasExtension(const std::string& filename, const std::string& extension) { } return (0 == filename.compare(fileLen-extLen, extLen, extension)); } + +bool checkTizenIdExist(const std::string& tizenId) { + std::string installPath = + std::string(GlobalConfig::GetUserInstalledWidgetPath()) + + "/" + tizenId; + std::string preinstallPath = + std::string(GlobalConfig::GetUserPreloadedWidgetPath()) + + "/" + tizenId; + + struct stat dirStat; + if ((stat(installPath.c_str(), &dirStat) == 0) && + (stat(preinstallPath.c_str(), &dirStat) == 0)) { + return true; + } + return false; +} } // namespace anonymous namespace Jobs { @@ -152,24 +174,28 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, // Create installation tasks if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_HOSTED_WEB_APP || !m_isDRM) { + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && + m_installerContext.widgetConfig.packagingType != + WrtDB::PKG_TYPE_HOSTED_WEB_APP && + !m_isDRM) + { AddTask(new TaskUnzip(m_installerContext)); } AddTask(new TaskWidgetConfig(m_installerContext)); - if (m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_HOSTED_WEB_APP ) { + if (m_installerContext.widgetConfig.packagingType == + WrtDB::PKG_TYPE_HOSTED_WEB_APP) + { AddTask(new TaskPrepareFiles(m_installerContext)); } AddTask(new TaskCertify(m_installerContext)); if (m_needEncryption) { AddTask(new TaskEncryptResource(m_installerContext)); } + AddTask(new TaskFileManipulation(m_installerContext)); // TODO: Update progress information for this task - AddTask(new TaskPrivateStorage(m_installerContext)); - //This is sort of quick solution, because ACE verdicts are based upon //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate //task. @@ -188,19 +214,28 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, LogInfo("Configure installation updated"); LogInfo("Widget Update"); if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_HOSTED_WEB_APP || !m_isDRM) { + WrtDB::PKG_TYPE_HOSTED_WEB_APP && + m_installerContext.widgetConfig.packagingType != + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && + !m_isDRM) + { AddTask(new TaskUnzip(m_installerContext)); } AddTask(new TaskWidgetConfig(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_HOSTED_WEB_APP ) { + WrtDB::PKG_TYPE_HOSTED_WEB_APP) + { AddTask(new TaskPrepareFiles(m_installerContext)); } AddTask(new TaskCertify(m_installerContext)); - AddTask(new TaskUpdateFiles(m_installerContext)); + if (m_installerContext.widgetConfig.packagingType != + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + { + AddTask(new TaskUpdateFiles(m_installerContext)); + } /* TODO : To backup file, save md5 values */ AddTask(new TaskSmack(m_installerContext)); @@ -210,7 +245,11 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, PKG_TYPE_HYBRID_WEB_APP) { AddTask(new TaskInstallOspsvc(m_installerContext)); } - AddTask(new TaskRemoveBackupFiles(m_installerContext)); + if (m_installerContext.widgetConfig.packagingType != + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + { + AddTask(new TaskRemoveBackupFiles(m_installerContext)); + } AddTask(new TaskPluginsCopy(m_installerContext)); AddTask(new TaskDatabase(m_installerContext)); AddTask(new TaskAceCheck(m_installerContext)); @@ -241,9 +280,10 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( Try { - std::string tempDir = Jobs::WidgetInstall::createTempPath(); + std::string tempDir = + Jobs::WidgetInstall::createTempPath(m_jobStruct.m_preload); - bool m_isDRM = isDRMWidget(widgetPath); + m_isDRM = isDRMWidget(widgetPath); if (true == m_isDRM) { LogDebug("decrypt DRM widget"); if(DecryptDRMWidget(widgetPath, tempDir)) { @@ -256,12 +296,16 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( m_installerContext.widgetConfig.packagingType = checkPackageType(widgetPath, tempDir); - ConfigParserData configData = getWidgetDataFromXML(widgetPath, tempDir, - m_installerContext.widgetConfig.packagingType, m_isDRM); + ConfigParserData configData = getWidgetDataFromXML( + widgetPath, + tempDir, + m_installerContext.widgetConfig.packagingType, + m_isDRM); LogDebug("widget packaging type : " << m_installerContext.widgetConfig.packagingType.pkgType); WidgetUpdateInfo update = detectWidgetUpdate(configData); m_needEncryption = detectResourceEncryption(configData); + setInstallLocationType(configData); // Configure installation result = ConfigureInstallation(widgetPath, configData, update, tempDir); @@ -275,31 +319,35 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( return result; } -std::string JobWidgetInstall::generateTizenId() { - std::string allowed("0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"); - std::string tizenId; - tizenId.resize(MAX_TIZENID_LENGTH); - for (int i = 0; i < MAX_TIZENID_LENGTH; ++i) { - tizenId[i] = allowed[rand() % allowed.length()]; - } - return tizenId; -} - bool JobWidgetInstall::setTizenId( - const WrtDB::ConfigParserData &configInfo, ConfigureResult result) + const WrtDB::ConfigParserData &configInfo, + const WidgetUpdateInfo &update, + bool preload) { + using namespace PackageManager; regex_t reg; - regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED); - struct stat dirStat; + if(regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){ + LogDebug("Regcomp failed"); + } + + ConfigureResult result = checkWidgetUpdate(update); if(!!configInfo.tizenId) { LogDebug("Setting tizenId provided in config.xml: " << configInfo.tizenId); + // send start signal of pkgmgr + getInstallerStruct().pkgmgrInterface->setPkgname( + DPL::ToUTF8String(*(configInfo.tizenId))); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_INSTALL); + + if (result == ConfigureResult::Failed) { + return false; + } + if ((regexec(®, DPL::ToUTF8String(*(configInfo.tizenId)).c_str(), static_cast(0), NULL, 0) != REG_NOERROR) || - ((stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/" - + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0) - && result != ConfigureResult::Updated)) + (checkTizenIdExist(DPL::ToUTF8String(*(configInfo.tizenId))) && + result != ConfigureResult::Updated)) { //it is true when tizenId does not fit REG_TIZENID_PATTERN LogError("tizen_id provided but not proper."); @@ -309,33 +357,31 @@ bool JobWidgetInstall::setTizenId( m_installerContext.widgetConfig.pkgname = configInfo.tizenId; } else { - std::string tizenId = generateTizenId(); + WidgetPkgName tizenId = WidgetDAOReadOnly::generateTizenId(); // only for installation, not for update if (result == ConfigureResult::Ok) { //check if there is package with same name and if generate different name - std::string path = GlobalConfig::GetUserInstalledWidgetPath(); - path += "/"; - - std::ostringstream newPath; - newPath << path << tizenId; LogDebug("Checking if tizen id is unique"); while (true) { - if (stat(newPath.str().c_str(), &dirStat) == 0) { + if (checkTizenIdExist(DPL::ToUTF8String(tizenId))) { //path exist, chose another one - tizenId = generateTizenId(); - newPath.str(""); - newPath << path << tizenId; + tizenId = WidgetDAOReadOnly::generateTizenId(); continue; } break; } - m_installerContext.widgetConfig.pkgname = - DPL::FromUTF8String(tizenId); + m_installerContext.widgetConfig.pkgname = tizenId; } LogInfo("tizen_id name was generated by WRT: " << tizenId); + // send start signal of pkgmgr + getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String( + *m_installerContext.widgetConfig.pkgname)); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_INSTALL); } regfree(®); @@ -344,18 +390,14 @@ bool JobWidgetInstall::setTizenId( return true; } -DPL::OptionalString JobWidgetInstall::getNewTizenId() const -{ - return m_installerContext.widgetConfig.pkgname; -} - void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, const std::string& tempPath) { m_installerContext.locations = WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname), widgetPath, tempPath, - m_installerContext.widgetConfig.packagingType); + m_installerContext.widgetConfig.packagingType, + m_installerContext.locationType); LogInfo("widgetSource " << widgetPath); } @@ -366,6 +408,27 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( const WidgetUpdateInfo &update, const std::string &tempPath) { + + if (!setTizenId(configData, update, m_jobStruct.m_preload)) { + return ConfigureResult::Failed; + } else { + LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname); + + configureWidgetLocation(widgetSource, tempPath); + } + + // Init installer context + m_installerContext.installStep = InstallerContext::INSTALL_START; + m_installerContext.job = this; + m_installerContext.existingWidgetInfo = update.existingWidgetInfo; + m_installerContext.widgetConfig.shareHref = std::string(); + + return ConfigureResult::Ok; +} + +JobWidgetInstall::ConfigureResult JobWidgetInstall::checkWidgetUpdate( + const WidgetUpdateInfo &update) +{ LogInfo( "Widget install/update: incoming guid = '" << update.incomingGUID << "'"); @@ -375,7 +438,6 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( // Check policy WidgetUpdateMode::Type updateTypeCheckBit; - JobWidgetInstall::ConfigureResult ret = ConfigureResult::Ok; if (update.existingWidgetInfo.isExist == false) { LogInfo("Widget info does not exist"); @@ -412,7 +474,6 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( } else { LogInfo( "Widget is already running. Policy is not update according to WAC"); - LogInfo("Installation aborted: " << widgetSource); return ConfigureResult::Failed; } @@ -426,39 +487,17 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion, incomingVersion); // Calc proceed flag - if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0) { + if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0 || + m_jobStruct.updateMode == + WidgetUpdateMode::PolicyDirectoryForceInstall) + { LogInfo("Whether widget policy allow proceed ok"); - ret = ConfigureResult::Updated; + return ConfigureResult::Updated; } else return ConfigureResult::Failed; } - - if (!setTizenId(configData, ret)) { - return ConfigureResult::Failed; - } else { - using namespace PackageManager; - LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname); - - configureWidgetLocation(widgetSource, tempPath); - - // send start signal of pkgmgr - PkgmgrSignalSingleton::Instance().setPkgname( - DPL::ToUTF8String( - *m_installerContext.widgetConfig.pkgname)); - PkgmgrSignalSingleton::Instance().sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_INSTALL); - } - - // Init installer context - m_installerContext.installStep = InstallerContext::INSTALL_START; - m_installerContext.job = this; - m_installerContext.existingWidgetInfo = update.existingWidgetInfo; - m_installerContext.widgetConfig.shareHref = std::string(); - - // Return result - return ret; + return ConfigureResult::Ok; } WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy( @@ -512,6 +551,12 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( new RootParser(configInfo, DPL::FromUTF32String( L"widget")))); + } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) { + parser.Parse(widgetSource + '/' + WITH_OSP_XML, + ElementParserPtr( + new RootParser( + configInfo, + DPL::FromUTF32String(L"widget")))); } else { if (!isDRM) { std::unique_ptr zipFile( @@ -578,6 +623,11 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( LogError("Failed to parse config.xml file"); return ConfigParserData(); } + Catch(DPL::ZipInput::Exception::SeekFileFailed) + { + LogError("Failed to seek widget archive - corrupted package?"); + return ConfigParserData(); + } return configInfo; } @@ -635,7 +685,7 @@ void JobWidgetInstall::SendProgress() // send progress signal of pkgmgr std::ostringstream percent; percent << static_cast(GetProgressPercent()); - PkgmgrSignalSingleton::Instance().sendSignal( + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_PROGRESS_KEY, percent.str()); @@ -652,16 +702,26 @@ void JobWidgetInstall::SendFinishedSuccess() // TODO : sync should move to separate task. sync(); + + if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) { + if (false == m_installerContext.existingWidgetInfo.isExist) { + WidgetInstallToExtSingleton::Instance().postInstallation(true); + } else { + WidgetInstallToExtSingleton::Instance().postUpgrade(true); + } + WidgetInstallToExtSingleton::Instance().deinitialize(); + } + // remove widget install information file unlink(m_installerContext.installInfo.c_str()); //inform widget info JobWidgetInstall::displayWidgetInfo(); - DPL::OptionalString tizenId = getNewTizenId(); + DPL::OptionalString & tizenId = m_installerContext.widgetConfig.pkgname; // send signal of pkgmgr - PkgmgrSignalSingleton::Instance().sendSignal( + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_END_KEY, PKGMGR_END_SUCCESS); @@ -678,12 +738,12 @@ void JobWidgetInstall::SendFinishedFailure() LogError("Error in installation step: " << m_exceptionCaught); LogError("Message: " << m_exceptionMessage); - DPL::OptionalString tizenId = getNewTizenId(); + DPL::OptionalString & tizenId = m_installerContext.widgetConfig.pkgname; LogDebug("Call widget install failure finishedCallback"); // send signal of pkgmgr - PkgmgrSignalSingleton::Instance().sendSignal( + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_END_KEY, PKGMGR_END_FAILURE); @@ -766,7 +826,12 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( const std::string &widgetSource, const std::string &tempPath) { - // Check installation type (config.xml or widget.wgt) + // Check installation type (direcotory/ or config.xml or widget.wgt) + if (WidgetUpdateMode::PolicyDirectoryForceInstall == m_jobStruct.updateMode) + { + LogDebug("Install directly from directory"); + return PKG_TYPE_DIRECTORY_WEB_APP; + } if (hasExtension(widgetSource, XML_EXTENSION)) { LogInfo("Hosted app installation"); return PKG_TYPE_HOSTED_WEB_APP; @@ -796,6 +861,11 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( LogDebug("Failed to open widget package"); return PKG_TYPE_UNKNOWN; } + Catch(DPL::ZipInput::Exception::SeekFileFailed) + { + LogError("Failed to seek widget package file"); + return PKG_TYPE_UNKNOWN; + } Try { @@ -840,6 +910,28 @@ bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &c return false; } +void JobWidgetInstall::setInstallLocationType(const + WrtDB::ConfigParserData &configData) +{ + m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL; + + if (true == m_jobStruct.m_preload) { + m_installerContext.locationType = + INSTALL_LOCATION_TYPE_PRELOAD; + } else { + FOREACH(it, configData.settingsList) + { + if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME && + it->m_value == + SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) { + LogDebug("This widget will be installed to sd card"); + m_installerContext.locationType = + INSTALL_LOCATION_TYPE_EXTERNAL; + } + } + } +} + bool JobWidgetInstall::isDRMWidget(std::string widgetPath) { /* TODO : @@ -862,7 +954,7 @@ bool JobWidgetInstall::isDRMWidget(std::string widgetPath) bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath, std::string destPath) { - /* TODO : + /* TODO : drm_trusted_sapps_decrypt_package_info_s package_info; strncpy(package_info.sadcf_filepath, widgetPath.c_str(), @@ -882,7 +974,7 @@ bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath, } */ if (drm_oem_intel_decrypt_package(const_cast(widgetPath.c_str()), - const_cast(destPath.c_str())) != 0) { + const_cast(destPath.c_str())) != 0) { return true; } else { return false; diff --git a/src/jobs/widget_install/job_widget_install.h b/src/jobs/widget_install/job_widget_install.h index fa39392..1f81498 100644 --- a/src/jobs/widget_install/job_widget_install.h +++ b/src/jobs/widget_install/job_widget_install.h @@ -72,7 +72,8 @@ class JobWidgetInstall : const OptionalWidgetVersion &existingVersion, const OptionalWidgetVersion &incomingVersion) const; bool setTizenId(const WrtDB::ConfigParserData &configInfo, - ConfigureResult result); + const WidgetUpdateInfo &update, + bool preload); void displayWidgetInfo(); void configureWidgetLocation(const std::string & widgetPath, const std::string &tempPath); @@ -81,10 +82,12 @@ class JobWidgetInstall : const std::string &widgetSource, const std::string &tempPath); bool detectResourceEncryption(const WrtDB::ConfigParserData &configData); - std::string generateTizenId(); + void setInstallLocationType(const WrtDB::ConfigParserData + &configData); bool isDRMWidget(std::string widgetPath); bool DecryptDRMWidget(std::string widgetPath, std::string destPath); ConfigureResult PrePareInstallation(const std::string &widgetPath); + ConfigureResult checkWidgetUpdate(const WidgetUpdateInfo &update); public: /** @@ -93,8 +96,6 @@ class JobWidgetInstall : JobWidgetInstall(std::string const & widgetPath, const WidgetInstallationStruct &installerStruct); - DPL::OptionalString getNewTizenId() const; - //overrides void SendProgress(); void SendFinishedSuccess(); diff --git a/src/jobs/widget_install/manifest.cpp b/src/jobs/widget_install/manifest.cpp old mode 100644 new mode 100755 index f231d02..98adb96 --- a/src/jobs/widget_install/manifest.cpp +++ b/src/jobs/widget_install/manifest.cpp @@ -176,6 +176,7 @@ void Manifest::serialize(xmlTextWriterPtr 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); } } endElement(writer); } @@ -210,7 +211,7 @@ void ServiceApplication::serialize(xmlTextWriterPtr writer) writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang", i->getLang(), i->hasLang()); } - FOREACH(a, this->applicationService) + FOREACH(a, this->appControl) { a->serialize(writer); } @@ -242,10 +243,16 @@ void UiApplication::serialize(xmlTextWriterPtr writer) writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang", i->getLang(), i->hasLang()); } - FOREACH(a, this->applicationService) + FOREACH(a, this->appControl) { a->serialize(writer); } + FOREACH(c, this->appCategory) + { + startElement(writer, "category"); + writeAttribute(writer, "name", *c); + endElement(writer); + } endElement(writer); } @@ -272,9 +279,9 @@ void ImeApplication::serialize(xmlTextWriterPtr writer) endElement(writer); } -void ApplicationService::serialize(xmlTextWriterPtr writer) +void AppControl::serialize(xmlTextWriterPtr writer) { - startElement(writer, "application-service"); + startElement(writer, "app-control"); FOREACH(o, this->operation) { startElement(writer, "operation"); @@ -296,5 +303,83 @@ void ApplicationService::serialize(xmlTextWriterPtr 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()) { + startElement(writer, "label"); + writeText(writer, this->label); + 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.boxSize.empty()) + { + startElement(writer, "box"); + writeAttribute(writer, "type", "buffer"); + + FOREACH(m, this->box.boxSize) + { + std::pair boxSize = *m; + startElement(writer, "size"); + if(!boxSize.second.empty()) + writeAttribute(writer, "preview", boxSize.second); + writeText(writer, boxSize.first); + 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); +} + } //namespace Jobs } //namespace WidgetInstall diff --git a/src/jobs/widget_install/manifest.h b/src/jobs/widget_install/manifest.h old mode 100644 new mode 100755 index 84894dd..ac469d2 --- a/src/jobs/widget_install/manifest.h +++ b/src/jobs/widget_install/manifest.h @@ -61,6 +61,7 @@ typedef StringWithLang LabelType, IconType, DescriptionType; typedef DPL::String NcnameType, NmtokenType, AnySimpleType, LangType; typedef DPL::String OperationType, MimeType, UriType, TypeType, PackageType; typedef DPL::OptionalString InstallLocationType, CategoriesType; +typedef DPL::String AppCategoryType; /** * xmllib2 wrappers @@ -103,10 +104,10 @@ typedef Author AuthorType; /** * @brief application-service element */ -class ApplicationService +class AppControl { public: - ApplicationService() {} + 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); } @@ -117,7 +118,7 @@ private: std::list mime; //attr name AnySimpleType }; -typedef ApplicationService ApplicationServiceType; +typedef AppControl AppControlType; /** * @brief ime-application element @@ -160,9 +161,9 @@ public: 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 addApplicationService(const ApplicationServiceType &x) + void addAppControl(const AppControlType &x) { - this->applicationService.push_back(x); + this->appControl.push_back(x); } void serialize(xmlTextWriterPtr writer); private: @@ -173,7 +174,7 @@ private: TypeType type; std::list label; //attr name AnySimpleType std::list icon; //attr name AnySimpleType - std::list applicationService; //attr name AnySimpleType + std::list appControl; //attr name AnySimpleType }; typedef ServiceApplication ServiceApplicationType; @@ -195,9 +196,13 @@ public: 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 addApplicationService(const ApplicationServiceType &x) + void addAppControl(const AppControlType &x) { - this->applicationService.push_back(x); + this->appControl.push_back(x); + } + void addAppCategory(const AppCategoryType &x) + { + this->appCategory.push_back(x); } void serialize(xmlTextWriterPtr writer); private: @@ -211,12 +216,56 @@ private: CategoriesType categories; std::list label; std::list icon; - std::list applicationService; + std::list appControl; + std::list appCategory; }; typedef UiApplication UiApplicationType; /** + * @brief LiveBox element + */ +typedef std::list> boxSizeType; + + +struct BoxInfo +{ + NcnameType boxSrc; + 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 NcnameType &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; + NcnameType label; + NcnameType icon; + BoxInfoType box; +}; + +typedef LiveBox LiveBoxInfo; + +/** * @brief manifest element * * Manifest xml file representation. @@ -257,6 +306,11 @@ public: } // void addFont(const FontType &x) { this->font.push_back(x); } + void addLivebox(const LiveBoxInfo &x) + { + this->livebox.push_back(x); + } + void setInstallLocation(const InstallLocationType &x) { this->installLocation = x; @@ -275,6 +329,7 @@ private: std::list uiApplication; std::list imeApplication; // std::list font; + std::list livebox; InstallLocationType installLocation; NcnameType package; PackageType type; diff --git a/src/jobs/widget_install/task_certificates.cpp b/src/jobs/widget_install/task_certificates.cpp index a302b64..4e41048 100755 --- a/src/jobs/widget_install/task_certificates.cpp +++ b/src/jobs/widget_install/task_certificates.cpp @@ -83,49 +83,74 @@ void TaskCertificates::SetCertiInfo(CertificateSource source) FOREACH(it, certificateChainList) { - LogDebug("Insert certinfo to pkgmgr db"); + LogDebug("Insert certinfo to pkgmgr structure"); ValidationCore::CertificateCollection chain; if (false == chain.load(*it)) { LogError("Chain is broken"); + ThrowMsg(Exceptions::SetCertificateInfoFailed, + "Failed to Installer Save Certinfo"); } - chain.sort(); + if (!chain.sort()){ + LogError("Chain failed at sorting"); + } ValidationCore::CertificateList list = chain.getCertificateList(); - FOREACH(certIt, list) { - ValidationCore::Crypto::Hash::SHA1 sha1; - sha1.Append((*certIt)->getDER()); - sha1.Finish(); - std::string sha1String = sha1.ToBase64String(); - - if ((*certIt)->isRootCert()) { - if (source == SIGNATURE_DISTRIBUTOR) { - LogDebug("Set SIGNATURE_DISTRIBUTOR "); - if((pkgmgr_installer_set_cert_value( - m_pkgHandle, - PM_SET_DISTRIBUTOR_ROOT_CERT, - const_cast(sha1String.c_str()))) < 0) { - LogError("pkgmgrInstallerSetCertValue fail"); - ThrowMsg(Exceptions::SetCertificateInfoFailed, - "Failed to Set CertValue"); + pkgmgr_instcert_type instCertType; + + if (source == SIGNATURE_DISTRIBUTOR) { + std::string + Name(DPL::ToUTF8String(*(*certIt)->getOrganizationName())); + size_t found = Name.find("Tizen"); + + if (found != std::string::npos) { + LogDebug("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 { + LogDebug("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 { - LogDebug("set SIGNATURE_AUTHOR"); - if((pkgmgr_installer_set_cert_value( - m_pkgHandle, - PM_SET_AUTHOR_ROOT_CERT, - const_cast(sha1String.c_str()))) < 0) { - LogError("pkgmgrInstallerSetCertValue fail"); - ThrowMsg(Exceptions::SetCertificateInfoFailed, - "Failed to Installer Set CertValue"); + } else { + LogDebug("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; } } } + LogDebug("cert type : " << instCertType); + if((pkgmgr_installer_set_cert_value( + m_pkgHandle, + instCertType, + const_cast(((*certIt)->getBase64()).c_str()))) < 0) { + LogError("pkgmgrInstallerSetCertValue fail"); + ThrowMsg(Exceptions::SetCertificateInfoFailed, + "Failed to Set CertValue"); + } } } } diff --git a/src/jobs/widget_install/task_certify.cpp b/src/jobs/widget_install/task_certify.cpp index 532c206..40a17cd 100755 --- a/src/jobs/widget_install/task_certify.cpp +++ b/src/jobs/widget_install/task_certify.cpp @@ -37,9 +37,10 @@ #include #include "wac_widget_id.h" +#include #include #include -#include +#include #include #include #include @@ -83,11 +84,11 @@ WidgetCertificateData toWidgetCertificateData(const SignatureData &data, result.strCommonName = *certificate->getCommonName(); result.strMD5Fingerprint = std::string("md5 ") + - SignatureValidator::FingerprintToColonHex( + Certificate::FingerprintToColonHex( certificate->getFingerprint(Certificate::FINGERPRINT_MD5)); result.strSHA1Fingerprint = std::string("sha-1 ") + - SignatureValidator::FingerprintToColonHex( + Certificate::FingerprintToColonHex( certificate->getFingerprint(Certificate::FINGERPRINT_SHA1)); return result; @@ -101,10 +102,7 @@ TaskCertify::TaskCertify(InstallerContext &inCont) : m_contextData(inCont), WidgetInstallPopup(inCont) { - /* This is temporary comment for certi error - After security-server, cert-svc release, should remove comment AddStep(&TaskCertify::stepSignature); - */ // Block until fixed popup issues if (!GlobalSettings::PopupsTestModeEnabled() @@ -131,7 +129,9 @@ void TaskCertify::processDistributorSignature(const SignatureData &data, CertificateCollection collection; collection.load(data.getCertList()); - collection.sort(); + 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."); @@ -186,7 +186,7 @@ void TaskCertify::processAuthorSignature(const SignatureData &data) void TaskCertify::stepSignature() { - LogInfo("enter"); + LogInfo("================ Step: <> ENTER ==============="); std::string widgetPath = m_contextData.locations->getTemporaryRootDir() + "/"; @@ -199,7 +199,7 @@ void TaskCertify::stepSignature() } SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin(); - LogInfo("No of signatures: " << signatureFiles.size()); + LogInfo("Number of signatures: " << signatureFiles.size()); bool firstDistributorSignature = true; bool testCertificate = false; @@ -216,19 +216,28 @@ void TaskCertify::stepSignature() xml.initialize(data, GlobalConfig::GetSignatureXmlSchema()); xml.read(data); - SignatureValidator validator(!GlobalSettings::OCSPTestModeEnabled(), - !GlobalSettings::CrlTestModeEnabled(), - complianceMode); - SignatureValidator::Result result = + WrtSignatureValidator::AppType appType = WrtSignatureValidator::WAC20; + + if (m_installContext.widgetConfig.webAppType == APP_TYPE_TIZENWEBAPP) { + appType = WrtSignatureValidator::TIZEN; + } + + WrtSignatureValidator validator( + appType, + !GlobalSettings::OCSPTestModeEnabled(), + !GlobalSettings::CrlTestModeEnabled(), + complianceMode); + + WrtSignatureValidator::Result result = validator.check(data, widgetPath); - if (result == SignatureValidator::SIGNATURE_REVOKED) { + if (result == WrtSignatureValidator::SIGNATURE_REVOKED) { LogWarning("Certificate is REVOKED"); ThrowMsg(Exceptions::InvalidPackage, "Certificate is REVOKED"); } - if (result == SignatureValidator::SIGNATURE_INVALID) { + if (result == WrtSignatureValidator::SIGNATURE_INVALID) { LogWarning("Signature is INVALID"); // TODO change exception name ThrowMsg(Exceptions::InvalidPackage, @@ -236,15 +245,15 @@ void TaskCertify::stepSignature() } if (data.isAuthorSignature()) { - if (result == SignatureValidator::SIGNATURE_VERIFIED || + if (result == WrtSignatureValidator::SIGNATURE_VERIFIED || m_contextData.wacSecurity.isDistributorSigned()) { processAuthorSignature(data); - } else if (result == SignatureValidator::SIGNATURE_DISREGARD) { + } else if (result == WrtSignatureValidator::SIGNATURE_DISREGARD) { continue; } } else { - if (result == SignatureValidator::SIGNATURE_DISREGARD) { + if (result == WrtSignatureValidator::SIGNATURE_DISREGARD) { continue; } // now signature _must_ be verified @@ -300,7 +309,7 @@ void TaskCertify::stepSignature() LogInfo("No signature files has been found."); } - LogInfo("================ Step: <> DONE ================"); + LogInfo("================ Step: <> DONE ================"); m_contextData.job->UpdateProgress( InstallerContext::INSTALL_DIGSIG_CHECK, diff --git a/src/jobs/widget_install/task_commons.cpp b/src/jobs/widget_install/task_commons.cpp index 10c73e8..fea9ea1 100644 --- a/src/jobs/widget_install/task_commons.cpp +++ b/src/jobs/widget_install/task_commons.cpp @@ -43,14 +43,19 @@ const mode_t TEMPORARY_PATH_MODE = 0775; } // namespace -std::string createTempPath() +std::string createTempPath(bool preload) { LogInfo("Step: Creating temporary path"); // Temporary path std::ostringstream tempPathBuilder; - tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); + if (preload) { + tempPathBuilder << WrtDB::GlobalConfig::GetUserPreloadedWidgetPath(); + } else { + tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); + } + tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath(); tempPathBuilder << "/"; tempPathBuilder << TEMPORARY_PATH_POSTFIX; tempPathBuilder << "_"; diff --git a/src/jobs/widget_install/task_commons.h b/src/jobs/widget_install/task_commons.h index dbb41eb..5193c3d 100644 --- a/src/jobs/widget_install/task_commons.h +++ b/src/jobs/widget_install/task_commons.h @@ -29,7 +29,8 @@ namespace WidgetInstall { //TODO make directory like jobs common? -std::string createTempPath(); +std::string createTempPath(bool preload = false); +std::string createTempPath(bool preload); void createTempPath(const std::string& path); diff --git a/src/jobs/widget_install/task_database.cpp b/src/jobs/widget_install/task_database.cpp index f861c85..696a962 100644 --- a/src/jobs/widget_install/task_database.cpp +++ b/src/jobs/widget_install/task_database.cpp @@ -26,31 +26,41 @@ #include #include #include -//#include #include +#include #include #include #include #include -//#include #include #include +#include +#include +#include +#include +#include using namespace WrtDB; namespace Jobs { namespace WidgetInstall { + TaskDatabase::TaskDatabase(InstallerContext& context) : DPL::TaskDecl(this), - m_context(context) + m_context(context), + m_handleToRemove(INVALID_WIDGET_HANDLE), + m_handle(INVALID_WIDGET_HANDLE) { AddStep(&TaskDatabase::StepRegisterExternalFiles); - AddStep(&TaskDatabase::StepDBInsert); + AddStep(&TaskDatabase::StepWrtDBInsert); + AddStep(&TaskDatabase::StepAceDBInsert); + AddStep(&TaskDatabase::StepRemoveExternalFiles); + AddStep(&TaskDatabase::StepCreateVconf); AddAbortStep(&TaskDatabase::StepAbortDBInsert); } -void TaskDatabase::StepDBInsert() +void TaskDatabase::StepWrtDBInsert() { Try { @@ -59,11 +69,15 @@ void TaskDatabase::StepDBInsert() if (m_context.existingWidgetInfo.isExist) //update { + m_handleToRemove = WidgetDAOReadOnly::getHandle( + m_context.locations->getPkgname()); LogInfo("Registering widget... (update)"); WidgetDAO::registerOrUpdateWidget( m_context.locations->getPkgname(), m_context.widgetConfig, m_context.wacSecurity); + m_handle = WidgetDAOReadOnly::getHandle( + m_context.locations->getPkgname()); } else //new installation { @@ -72,6 +86,8 @@ void TaskDatabase::StepDBInsert() m_context.locations->getPkgname(), m_context.widgetConfig, m_context.wacSecurity); + m_handle = WidgetDAOReadOnly::getHandle( + m_context.locations->getPkgname()); } FOREACH (cap, m_context.staticPermittedDevCaps) { @@ -91,6 +107,27 @@ void TaskDatabase::StepDBInsert() LogError("Database failure!"); ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!"); } +} + +void TaskDatabase::StepAceDBInsert() +{ + LogDebug("Inserting Ace database entry. New handle: " << m_handle); + if (INVALID_WIDGET_HANDLE != m_handleToRemove) { + LogDebug("Removing old insallation. Handle: " << m_handleToRemove); + if (ACE_OK != ace_unregister_widget( + static_cast(m_handleToRemove))) + { + LogWarning("Error while removing ace entry for previous insallation"); + }; + } + + if(!AceApi::registerAceWidget(m_handle, m_context.widgetConfig, + m_context.wacSecurity.getCertificateList())) + { + LogError("ace database insert failed"); + ThrowMsg(Exceptions::NotAllowed, "Update failure. ace_register_widget failed"); + } + LogDebug("Ace data inserted"); m_context.job->UpdateProgress( InstallerContext::INSTALL_NEW_DB_INSERT, @@ -104,28 +141,11 @@ void TaskDatabase::StepRegisterExternalFiles() { WidgetDAO dao(m_context.locations->getPkgname()); WrtDB::ExternalLocationList externalLocationsDB = dao.getWidgetExternalLocations(); - LogDebug("Removing external files:"); FOREACH(file, externalLocationsDB) { if(std::find(externalLocationsUpdate.begin(), externalLocationsUpdate.end(), *file) == externalLocationsUpdate.end()) { - if(WrtUtilFileExists(*file)) - { - LogDebug(" -> " << *file); - remove(file->c_str()); - } - else if(WrtUtilDirExists(*file)) - { - LogDebug(" -> " << *file); - if(!WrtUtilRemove(*file)){ - ThrowMsg(Exceptions::RemovingFolderFailure, - "Failed to remove external directory"); - } - } - else - { - LogWarning(" -> " << *file << "(no such a path)"); - } + m_externalLocationsToRemove.push_back(*file); } } } @@ -135,23 +155,97 @@ void TaskDatabase::StepRegisterExternalFiles() LogDebug(" -> " << *file); } - //set external lcoations to be registered + //set external locations to be registered m_context.widgetConfig.externalLocations = externalLocationsUpdate; } +void TaskDatabase::StepRemoveExternalFiles() +{ + if(!m_externalLocationsToRemove.empty()) + { + LogDebug("Removing external files:"); + } + + FOREACH(file, m_externalLocationsToRemove) + { + if(WrtUtilFileExists(*file)) + { + LogDebug(" -> " << *file); + remove(file->c_str()); + } + else if(WrtUtilDirExists(*file)) + { + LogDebug(" -> " << *file); + if(!WrtUtilRemove(*file)){ + ThrowMsg(Exceptions::RemovingFolderFailure, + "Failed to remove external directory"); + } + } + else + { + LogWarning(" -> " << *file << "(no such a path)"); + } + } +} + +void TaskDatabase::StepCreateVconf() +{ + LogDebug("StepCreateVconf"); + std::string popupUsageKey = + WrtDB::VconfConfig::GetVconfKeyPopupUsage( + m_context.locations->getPkgname()); + std::string geolocationUsageKey = + WrtDB::VconfConfig::GetVconfKeyGeolocationUsage( + m_context.locations->getPkgname()); + std::string webNotificationUsageKey = + WrtDB::VconfConfig::GetVconfKeyWebNotificationUsage( + m_context.locations->getPkgname()); + std::string webDatabaseUsageKey = + WrtDB::VconfConfig::GetVconfKeyWebDatabaseUsage( + m_context.locations->getPkgname()); + std::string filesystemUsageKey = + WrtDB::VconfConfig::GetVconfKeyFilesystemUsage( + m_context.locations->getPkgname()); + std::string memorySavingModeKey = + WrtDB::VconfConfig::GetVconfKeyMemorySavingMode( + m_context.locations->getPkgname()); + + vconf_set_int(popupUsageKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_ON)); + // prevent permission error + vconf_unset(popupUsageKey.c_str()); + vconf_set_int(popupUsageKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_ON)); + vconf_set_int(geolocationUsageKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_ON)); + vconf_set_int(webNotificationUsageKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_ON)); + vconf_set_int(webDatabaseUsageKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_ON)); + vconf_set_int(filesystemUsageKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_ON)); + vconf_set_int(memorySavingModeKey.c_str(), + static_cast(WrtDB::SETTINGS_TYPE_OFF)); +} + void TaskDatabase::StepAbortDBInsert() { LogWarning("[DB Update Task] Aborting... (DB Clean)"); Try { WidgetDAO::unregisterWidget(m_context.locations->getPkgname()); - LogDebug("Cleaning DB successful!"); } Catch(DPL::DB::SqlConnection::Exception::Base) { LogError("Failed to handle StepAbortDBClean!"); } + + ace_unregister_widget(static_cast(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(m_handle)); } } //namespace WidgetInstall diff --git a/src/jobs/widget_install/task_database.h b/src/jobs/widget_install/task_database.h index ce01985..f2098bc 100644 --- a/src/jobs/widget_install/task_database.h +++ b/src/jobs/widget_install/task_database.h @@ -24,6 +24,9 @@ #define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DATABASE_H #include +#include + +#include class InstallerContext; @@ -34,9 +37,18 @@ class 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; - void StepDBInsert(); void StepRegisterExternalFiles(); + void StepWrtDBInsert(); + void StepAceDBInsert(); + void StepRemoveExternalFiles(); + void StepCreateVconf(); void StepAbortDBInsert(); diff --git a/src/jobs/widget_install/task_db_update.cpp b/src/jobs/widget_install/task_db_update.cpp deleted file mode 100644 index 5b02a95..0000000 --- a/src/jobs/widget_install/task_db_update.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace WrtDB; - -namespace Jobs { -namespace WidgetInstall { -TaskDbUpdate::TaskDbUpdate(InstallerContext& context) : - DPL::TaskDecl(this), - m_context(context) -{ - AddStep(&TaskDbUpdate::StepDbUpdate); - - AddAbortStep(&TaskDbUpdate::StepAbortDBUpdate); -} - -void TaskDbUpdate::StepDbUpdate() -{ - Try - { - // If there is existing model, remove its database data - if (true == m_context.existingWidgetInfo.isExist) { - WidgetHandle old = m_context.existingWidgetInfo.existingHandle; - LogInfo("Unregistering widget...: " << old); - WidgetDAO::unregisterWidget(old); - LogInfo("Widget unregistered"); - } - - /* Set install Time */ - time(&m_context.widgetConfig.installedTime); - - LogInfo("Registering widget..."); - - WidgetDAO::registerWidget( - *(m_context.widgetHandle), - m_context.widgetConfig, - m_context.wacSecurity); - - FOREACH (cap, m_context.staticPermittedDevCaps) { - LogInfo("staticPermittedDevCaps : " << cap->first - << " smack status: " << cap->second); - } - - Assert(!!m_context.widgetConfig.pkgname - && "pkgName should be initialized"); - - WrtDB::WidgetDAO widgetDao(*m_context.widgetHandle); - widgetDao.setPkgName(m_context.widgetConfig.pkgname); - - LogInfo("Widget registered"); - } - Catch(WidgetDAO::Exception::DatabaseError) - { - LogWarning("Database failure!"); - ReThrowMsg(Exceptions::DatabaseFailure, "Database failure!"); - } - Catch(DPL::DB::SqlConnection::Exception::Base) - { - LogDebug("Database failure!"); - ReThrowMsg(Exceptions::DatabaseFailure, "Database failure!"); - } - - m_context.job->UpdateProgress( - InstallerContext::INSTALL_DB_UPDATE, - "Widget DB UPDATE Finished"); -} - -void TaskDbUpdate::StepAbortDBUpdate() -{ - LogWarning("[DB Update Task] Aborting... (DB Clean)"); - Assert(!!m_context.widgetHandle); - Try - { - WidgetDAO::unregisterWidget(*m_context.widgetHandle); - - LogDebug("Cleaning DB successful!"); - } - Catch(DPL::DB::SqlConnection::Exception::Base) - { - //TODO What should happen here? - LogError("Failed to handle StepAbortDBClean!"); - // ReThrowMsg(Exceptions::DbStepFailed, "Failed to handle StepAbortDBClean!"); - } -} - -} //namespace WidgetInstall -} //namespace Jobs diff --git a/src/jobs/widget_install/task_db_update.h b/src/jobs/widget_install/task_db_update.h deleted file mode 100644 index 3f76680..0000000 --- a/src/jobs/widget_install/task_db_update.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * @file task_db_update.h - * @author Lukasz Wrzosek(l.wrzosek@samsung.com) - * @version 1.0 - * @brief Header file for installer task database updating - */ -#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DB_UPDATE_H -#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DB_UPDATE_H - -#include - -class InstallerContext; - -namespace Jobs { -namespace WidgetInstall { -class TaskDbUpdate : - public DPL::TaskDecl -{ - private: - InstallerContext& m_context; - - void StepDbUpdate(); - - void StepAbortDBUpdate(); - - public: - TaskDbUpdate(InstallerContext& context); -}; -} //namespace WidgetInstall -} //namespace Jobs - -#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_DB_UPDATE_H diff --git a/src/jobs/widget_install/task_encrypt_resource.cpp b/src/jobs/widget_install/task_encrypt_resource.cpp index 9b0bdb4..2ea97ee 100644 --- a/src/jobs/widget_install/task_encrypt_resource.cpp +++ b/src/jobs/widget_install/task_encrypt_resource.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -161,17 +163,24 @@ void TaskEncryptResource::EncryptFile(const std::string &fileName) memset(readBuf, 0, fileSize); memset(outEncBuf, 0, blockSize); - fread(readBuf, sizeof(unsigned char), fileSize, resFp); - fclose(resFp); + ret = fread(readBuf, sizeof(unsigned char), fileSize, resFp); + if (ret!=fileSize){ + LogError("Failed to read ecryption buffer with error: " << strerror(errno) ); + fclose(resFp); + return; + } m_resEnc->EncryptChunk(readBuf, outEncBuf, fileSize); FILE* encFp = fopen(encFile.c_str(), "w"); if (NULL == encFp) { LogError("Failed to open ecryption file"); + fclose(resFp); return; } fwrite(outEncBuf, sizeof(unsigned char), blockSize, encFp); + + fclose(resFp); fclose(encFp); LogDebug("Success to encrypt file"); diff --git a/src/jobs/widget_install/task_file_manipulation.cpp b/src/jobs/widget_install/task_file_manipulation.cpp index ae02d73..a41239e 100644 --- a/src/jobs/widget_install/task_file_manipulation.cpp +++ b/src/jobs/widget_install/task_file_manipulation.cpp @@ -20,6 +20,7 @@ * @brief Implementation file for installer task database updating */ #include +#include #include #include #include @@ -28,20 +29,93 @@ #include #include #include +#include #include +#include +#include + +#define WEBAPP_DEFAULT_UID 5000 +#define WEBAPP_DEFAULT_GID 5000 + +namespace { +const mode_t PRIVATE_STORAGE_MODE = 0700; +const mode_t SHARE_MODE = 0705; +} using namespace WrtDB; +namespace { +const char* GLIST_RES_DIR = "res"; +const char* GLIST_BIN_DIR = "bin"; + +bool _FolderCopy(std::string source, std::string dest) +{ + DIR* dir = opendir(source.c_str()); + if (NULL == dir) { + return false; + } + + struct dirent* dEntry = NULL; + do { + struct stat statInfo; + if (dEntry = readdir(dir)) { + std::string fileName = dEntry->d_name; + std::string fullName = source + "/" + fileName; + + if (stat(fullName.c_str(), &statInfo) != 0) { + return false; + } + + if (S_ISDIR(statInfo.st_mode)) { + if(("." == fileName) || (".." == fileName)) { + continue; + } + std::string destFolder = dest + "/" + fileName; + WrtUtilMakeDir(destFolder); + + if (!_FolderCopy(fullName, destFolder)) { + return false; + } + } + + std::string destFile = dest + "/" + fileName; + std::ifstream infile(fullName); + std::ofstream outfile(destFile); + outfile << infile.rdbuf(); + outfile.close(); + infile.close(); + } + } while(dEntry); + closedir(dir); + return true; +} +} + namespace Jobs { namespace WidgetInstall { TaskFileManipulation::TaskFileManipulation(InstallerContext& context) : DPL::TaskDecl(this), m_context(context) { - AddStep(&TaskFileManipulation::StepCreateDirs); - AddStep(&TaskFileManipulation::StepRenamePath); + if (INSTALL_LOCATION_TYPE_EXTERNAL != + m_context.locationType) { + AddStep(&TaskFileManipulation::StepCreateDirs); + AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); + AddStep(&TaskFileManipulation::StepCreateShareDir); + if (m_context.widgetConfig.packagingType != + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + { + AddStep(&TaskFileManipulation::StepRenamePath); + AddAbortStep(&TaskFileManipulation::StepAbortRenamePath); + } + } else { + AddStep(&TaskFileManipulation::StepPrepareExternalDir); + AddStep(&TaskFileManipulation::StepInstallToExternal); + AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); + AddStep(&TaskFileManipulation::StepCreateShareDir); - AddAbortStep(&TaskFileManipulation::StepAbortRenamePath); + AddAbortStep(&TaskFileManipulation::StepAbortCreateExternalDir); + } } void TaskFileManipulation::StepCreateDirs() @@ -74,6 +148,91 @@ void TaskFileManipulation::StepCreateDirs() "Widget Directory Created"); } +void TaskFileManipulation::StepCreatePrivateStorageDir() +{ + std::string storagePath = m_context.locations->getPrivateStorageDir(); + + if (euidaccess(storagePath.c_str(), F_OK) != 0) { + if(!WrtUtilMakeDir(storagePath, PRIVATE_STORAGE_MODE)){ + LogError("Failed to create directory for private storage"); + ThrowMsg(Exceptions::InternalError, + "Failed to create directory for private storage"); + } + // '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(Exceptions::InternalError, + "Chown to invaild user"); + } + } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) { + LogInfo("Private storage already exists."); + // Even if private directory already is created, private dircetory + // should change owner. + if(chown(storagePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Exceptions::InternalError, + "Chown to invaild user"); + } + if(chmod(storagePath.c_str(), PRIVATE_STORAGE_MODE) != 0) { + ThrowMsg(Exceptions::InternalError, + "chmod to 0700"); + } + + } else { + ThrowMsg(Exceptions::InternalError, + "No access to private storage."); + } +} + +void TaskFileManipulation::StepCreateShareDir() +{ + std::string sharePath = m_context.locations->getShareDir(); + + if (euidaccess(sharePath.c_str(), F_OK) != 0) { + if(!WrtUtilMakeDir(sharePath, SHARE_MODE)){ + LogError("Failed to create directory for share"); + ThrowMsg(Exceptions::InternalError, + "Failed to create directory for share"); + } + // '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(sharePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Exceptions::InternalError, + "Chown to invaild user"); + } + } else if (euidaccess(sharePath.c_str(), W_OK | R_OK | X_OK) == 0) { + LogInfo("Share directory already exists."); + // Even if share directory already is created, share dircetory + // should change owner. + if(chown(sharePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Exceptions::InternalError, + "Chown to invaild user"); + } + if(chmod(sharePath.c_str(), SHARE_MODE) != 0) { + ThrowMsg(Exceptions::InternalError, + "chmod to 0700"); + } + + } else { + ThrowMsg(Exceptions::InternalError, + "No access to private storage."); + } + +} + void TaskFileManipulation::StepRenamePath() { std::string instDir; @@ -98,7 +257,6 @@ void TaskFileManipulation::StepRenamePath() ThrowMsg(Exceptions::UnknownError, "Error occurs during renaming widget folder"); } - m_context.job->UpdateProgress( InstallerContext::INSTALL_RENAME_PATH, "Widget Rename path Finished"); @@ -108,21 +266,90 @@ void TaskFileManipulation::StepAbortRenamePath() { LogDebug("[Rename Widget Path] Aborting.... (Rename path)"); std::string widgetPath; - if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) { + if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) { widgetPath = m_context.locations->getPackageInstallationDir(); - } else { - widgetPath = m_context.locations->getSourceDir(); + if (!WrtUtilRemove(widgetPath)) { + ThrowMsg(Exceptions::RemovingFolderFailure, + "Error occurs during removing existing folder"); + } } - struct stat fileInfo; - if (stat(widgetPath.c_str(), &fileInfo) != 0) { - LogError("Failed to get widget file path : " << widgetPath); - return; + LogDebug("Rename widget path sucessful!"); +} + +void TaskFileManipulation::StepPrepareExternalDir() +{ + LogDebug("Step prepare to install in exernal directory"); + Try { + std::string pkgname = + DPL::ToUTF8String(*m_context.widgetConfig.pkgname); + + WidgetInstallToExtSingleton::Instance().initialize(pkgname); + + size_t totalSize = + Utils::getFolderSize(m_context.locations->getTemporaryPackageDir()); + + int folderSize = (int)(totalSize / (1024 * 1024)) + 1; + + GList *list = NULL; + app2ext_dir_details* dirDetail = NULL; + + std::string dirNames[2] = {GLIST_RES_DIR, GLIST_BIN_DIR}; + + for (int i = 0; i < 2; i++) { + dirDetail = (app2ext_dir_details*) calloc(1, + sizeof(app2ext_dir_details)); + if (NULL == dirDetail) { + ThrowMsg(Exceptions::ErrorExternalInstallingFailure, "error in app2ext"); + } + dirDetail->name = strdup(dirNames[i].c_str()); + dirDetail->type = APP2EXT_DIR_RO; + list = g_list_append(list, dirDetail); + } + + if (false == m_context.existingWidgetInfo.isExist) { + WidgetInstallToExtSingleton::Instance().preInstallation(list, + folderSize); + } else { + WidgetInstallToExtSingleton::Instance().preUpgrade(list, + folderSize); + } + free(dirDetail); + g_list_free(list); + } + Catch (WidgetInstallToExt::Exception::ErrorInstallToExt) + { + ReThrowMsg(Exceptions::ErrorExternalInstallingFailure, "Error during \ + create external folder "); } +} - if (!(rename(widgetPath.c_str(), m_context.locations->getTemporaryPackageDir().c_str()) == 0)) { - LogError("Failed to rename"); +void TaskFileManipulation::StepInstallToExternal() +{ + LogDebug("StepInstallExternal"); + if (!WrtUtilMakeDir(m_context.locations->getSourceDir())) { + ThrowMsg(Exceptions::ErrorExternalInstallingFailure, "To make src \ + directory failed"); } - LogDebug("Rename widget path sucessful!"); + + LogDebug("Resource move to external storage " << + m_context.locations->getSourceDir()); + if (!_FolderCopy(m_context.locations->getTemporaryPackageDir(), + m_context.locations->getSourceDir())) + { + ThrowMsg(Exceptions::UnknownError, + "Error occurs during renaming widget folder"); + } +} + +void TaskFileManipulation::StepAbortCreateExternalDir() +{ + LogError("Abort StepAbortCreateExternalDir"); + if (false == m_context.existingWidgetInfo.isExist) { + WidgetInstallToExtSingleton::Instance().postInstallation(false); + } else { + WidgetInstallToExtSingleton::Instance().postUpgrade(false); + } + WidgetInstallToExtSingleton::Instance().deinitialize(); } } //namespace WidgetInstall } //namespace Jobs diff --git a/src/jobs/widget_install/task_file_manipulation.h b/src/jobs/widget_install/task_file_manipulation.h index 162dbbf..e3f615e 100644 --- a/src/jobs/widget_install/task_file_manipulation.h +++ b/src/jobs/widget_install/task_file_manipulation.h @@ -23,6 +23,7 @@ #define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_FILE_MANIPULATION_UPDATE_H #include +#include class InstallerContext; @@ -31,14 +32,23 @@ namespace WidgetInstall { class TaskFileManipulation : public DPL::TaskDecl { - private: InstallerContext& m_context; + app2ext_handle *m_extHandle; + // install internal location void StepCreateDirs(); void StepRenamePath(); + void StepCreatePrivateStorageDir(); + void StepCreateShareDir(); void StepAbortRenamePath(); + // install external location + void StepPrepareExternalDir(); + void StepInstallToExternal(); + void StepFinishExternalInstallation(); + void StepAbortCreateExternalDir(); + public: TaskFileManipulation(InstallerContext& context); }; diff --git a/src/jobs/widget_install/task_manifest_file.cpp b/src/jobs/widget_install/task_manifest_file.cpp old mode 100644 new mode 100755 index 3acb023..908109a --- a/src/jobs/widget_install/task_manifest_file.cpp +++ b/src/jobs/widget_install/task_manifest_file.cpp @@ -56,6 +56,9 @@ using namespace WrtDB; namespace { typedef std::map LanguageTagMap; +const char* const ST_TRUE = "true"; +const char* const ST_NODISPLAY = "nodisplay"; + LanguageTagMap getLanguageTagMap() { LanguageTagMap map; @@ -107,6 +110,8 @@ TaskManifestFile::TaskManifestFile(InstallerContext &inCont) : AddStep(&TaskManifestFile::stepGenerateManifest); AddStep(&TaskManifestFile::stepParseManifest); AddStep(&TaskManifestFile::stepFinalize); + + AddAbortStep(&TaskManifestFile::stepAbortParseManifest); } else { // for widget update. AddStep(&TaskManifestFile::stepBackupIconFiles); @@ -545,6 +550,8 @@ void TaskManifestFile::writeManifest(const DPL::String & path) setWidgetManifest(manifest); setWidgetOtherInfo(uiApp); setAppServiceInfo(uiApp); + setAppCategory(uiApp); + setLiveBoxInfo(manifest); manifest.addUiApplication(uiApp); manifest.generate(path); @@ -727,7 +734,17 @@ void TaskManifestFile::setWidgetManifest(Manifest & manifest) void TaskManifestFile::setWidgetOtherInfo(UiApplication & uiApp) { - uiApp.setNodisplay(false); + FOREACH(it, m_context.widgetConfig.configInfo.settingsList) + { + if(!strcmp(DPL::ToUTF8String(it->m_name).c_str(), ST_NODISPLAY)) { + if(!strcmp(DPL::ToUTF8String(it->m_value).c_str(), ST_TRUE)) { + uiApp.setNodisplay(true); + } + else { + uiApp.setNodisplay(false); + } + } + } //TODO //There is no "X-TIZEN-PackageType=wgt" //There is no X-TIZEN-PackageID in manifest "X-TIZEN-PackageID=" << DPL::ToUTF8String(*widgetID).c_str() @@ -746,19 +763,138 @@ void TaskManifestFile::setAppServiceInfo(UiApplication & uiApp) // x-tizen-svc=http://tizen.org/appcontrol/operation/pick|NULL|image; FOREACH(it, appServiceList) { - ApplicationService appService; + AppControl appControl; if (!it->m_operation.empty()) { - appService.addOperation(it->m_operation); //TODO: encapsulation? + appControl.addOperation(it->m_operation); //TODO: encapsulation? } if (!it->m_scheme.empty()) { - appService.addUri(it->m_scheme); + appControl.addUri(it->m_scheme); } if (!it->m_mime.empty()) { - appService.addMime(it->m_mime); + appControl.addMime(it->m_mime); + } + uiApp.addAppControl(appControl); + } +} + +void TaskManifestFile::setAppCategory(UiApplication &uiApp) +{ + WrtDB::ConfigParserData::CategoryList categoryList = + m_context.widgetConfig.configInfo.categoryList; + + if (categoryList.empty()) { + LogInfo("Widget doesn't contain application category"); + return; + } + FOREACH(it, categoryList) { + if (!(*it).empty()) { + uiApp.addAppCategory(*it); } - uiApp.addApplicationService(appService); } } +void TaskManifestFile::stepAbortParseManifest() +{ + LogError("[Parse Manifest] Abroting...."); + + int code = pkgmgr_parser_parse_manifest_for_uninstallation( + DPL::ToUTF8String(manifest_file).c_str(), NULL); + + if (0 != code) + { + LogWarning("Manifest parser error: " << code); + ThrowMsg(ManifestParsingError, "Parser returncode: " << code); + } + int ret = unlink(DPL::ToUTF8String(manifest_file).c_str()); + if (0 != ret) + { + LogWarning("No manifest file found: " << manifest_file); + } +} + +void TaskManifestFile::setLiveBoxInfo(Manifest& manifest) +{ + FOREACH(it, m_context.widgetConfig.configInfo.m_livebox) { + LogInfo("setLiveBoxInfo"); + LiveBoxInfo liveBox; + DPL::Optional ConfigInfo = *it; + DPL::String pkgname = *m_context.widgetConfig.pkgname; + size_t found; + + if(ConfigInfo->m_liveboxId != L"") { + found = ConfigInfo->m_liveboxId.find_first_of(L"."); + if(found != std::string::npos) { + if(0 == ConfigInfo->m_liveboxId.compare(0, found, pkgname)) + liveBox.setLiveboxId(ConfigInfo->m_liveboxId); + else { + DPL::String liveboxId = + pkgname+DPL::String(L".")+ConfigInfo->m_liveboxId; + liveBox.setLiveboxId(liveboxId); + } + } else { + DPL::String liveboxId = + pkgname+DPL::String(L".")+ConfigInfo->m_liveboxId; + liveBox.setLiveboxId(liveboxId); + } + } + + if(ConfigInfo->m_primary != L"") + liveBox.setPrimary(ConfigInfo->m_primary); + + if(ConfigInfo->m_autoLaunch == L"true") + liveBox.setAutoLaunch(pkgname); + + if(ConfigInfo->m_updatePeriod != L"") + liveBox.setUpdatePeriod(ConfigInfo->m_updatePeriod); + + if(ConfigInfo->m_label != L"") + liveBox.setLabel(ConfigInfo->m_label); + + DPL::String defaultLocale + = DPL::FromUTF8String(m_context.locations->getPackageInstallationDir()) + + DPL::String(L"/res/wgt/"); + + if(ConfigInfo->m_icon!=L"") { + liveBox.setIcon(defaultLocale+ConfigInfo->m_icon); + } + + if (ConfigInfo->m_boxInfo.m_boxSrc.empty() || ConfigInfo->m_boxInfo.m_boxSize.empty()) { + LogInfo("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; + } + + std::list> BoxSizeList + = ConfigInfo->m_boxInfo.m_boxSize; + FOREACH(im, BoxSizeList) { + std::pair boxSize = *im; + if(!boxSize.second.empty()) + boxSize.second = defaultLocale + boxSize.second; + box.boxSize.push_back(boxSize); + } + + if (!ConfigInfo->m_boxInfo.m_pdSrc.empty() + && !ConfigInfo->m_boxInfo.m_pdWidth.empty() + && !ConfigInfo->m_boxInfo.m_pdHeight.empty()) { + 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); + } + +} + } //namespace WidgetInstall } //namespace Jobs diff --git a/src/jobs/widget_install/task_manifest_file.h b/src/jobs/widget_install/task_manifest_file.h old mode 100644 new mode 100755 index 86edffe..191bc49 --- a/src/jobs/widget_install/task_manifest_file.h +++ b/src/jobs/widget_install/task_manifest_file.h @@ -68,6 +68,8 @@ class TaskManifestFile : void stepParseManifest(); void stepParseUpgradedManifest(); + void stepAbortParseManifest(); + //For widget update void stepBackupIconFiles(); void stepUpdateFinalize(); @@ -93,6 +95,8 @@ class TaskManifestFile : void setWidgetManifest(Manifest & manifest); void setWidgetOtherInfo(UiApplication & uiApp); void setAppServiceInfo(UiApplication & uiApp); + void setAppCategory(UiApplication & uiApp); + void setLiveBoxInfo(Manifest& manifest); void generateWidgetName(Manifest & manifest, UiApplication &uiApp, const DPL::OptionalString& tag, DPL::OptionalString name, bool & defaultNameSaved); void generateWidgetIcon(UiApplication & uiApp, const DPL::OptionalString& tag, const DPL::String& language, bool & defaultIconSaved); diff --git a/src/jobs/widget_install/task_new_db_insert.cpp b/src/jobs/widget_install/task_new_db_insert.cpp deleted file mode 100644 index 38e9d92..0000000 --- a/src/jobs/widget_install/task_new_db_insert.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR 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 -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -//#include -#include -#include - -using namespace WrtDB; - -namespace Jobs { -namespace WidgetInstall { -TaskNewDbInsert::TaskNewDbInsert(InstallerContext& context) : - DPL::TaskDecl(this), - m_context(context) -{ - AddStep(&TaskNewDbInsert::StepDBInsert); - - AddAbortStep(&TaskNewDbInsert::StepAbortDBInsert); -} - -void TaskNewDbInsert::StepDBInsert() -{ - Try - { - /* Set install Time */ - time(&m_context.widgetConfig.installedTime); - - LogInfo("Registering widget..."); - - WidgetDAO::registerWidget( - *(m_context.widgetHandle), - m_context.widgetConfig, - m_context.wacSecurity); - - FOREACH (cap, m_context.staticPermittedDevCaps) { - LogInfo("staticPermittedDevCaps : " << cap->first - << " smack status: " << cap->second); - } - - Assert(!!m_context.widgetConfig.pkgname - && "pkgName should be initialized"); - - WrtDB::WidgetDAO widgetDao(*m_context.widgetHandle); - widgetDao.setPkgName(m_context.widgetConfig.pkgname); - - LogInfo("Widget registered"); - } - Catch(WidgetDAO::Exception::DatabaseError) - { - LogWarning("Database failure!"); - ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!"); - } - Catch(DPL::DB::SqlConnection::Exception::Base) - { - LogDebug("Database failure!"); - ReThrowMsg(Exceptions::InsertNewWidgetFailed, "Database failure!"); - } - - m_context.job->UpdateProgress( - InstallerContext::INSTALL_NEW_DB_INSERT, - "New Widget DB UPDATE Finished"); -} - -void TaskNewDbInsert::StepAbortDBInsert() -{ - LogWarning("[DB Update Task] Aborting... (DB Clean)"); - Assert(!!m_context.widgetHandle); - Try - { - WidgetDAO::unregisterWidget(*m_context.widgetHandle); - - LogDebug("Cleaning DB successful!"); - } - Catch(DPL::DB::SqlConnection::Exception::Base) - { - LogError("Failed to handle StepAbortDBClean!"); - } -} - -} //namespace WidgetInstall -} //namespace Jobs diff --git a/src/jobs/widget_install/task_new_db_insert.h b/src/jobs/widget_install/task_new_db_insert.h deleted file mode 100644 index 13290d4..0000000 --- a/src/jobs/widget_install/task_new_db_insert.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR 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.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 for widget update - */ -#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_NEW_DB_INSERT_H -#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_NEW_DB_INSERT_H - -#include - -class InstallerContext; - -namespace Jobs { -namespace WidgetInstall { -class TaskNewDbInsert: - public DPL::TaskDecl -{ - private: - InstallerContext& m_context; - - void StepDBInsert(); - - void StepAbortDBInsert(); - - public: - TaskNewDbInsert(InstallerContext& context); -}; -} //namespace WidgetInstall -} //namespace Jobs - -#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_NEW_DB_INSERT_H diff --git a/src/jobs/widget_install/task_private_storage.cpp b/src/jobs/widget_install/task_private_storage.cpp deleted file mode 100644 index 8d9934f..0000000 --- a/src/jobs/widget_install/task_private_storage.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @file installer_task_private_storage.cpp - * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) - * @version 1.0 - * @brief Implementation file for installer task private storage. - */ -#include "task_private_storage.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define WEBAPP_DEFAULT_UID 5000 -#define WEBAPP_DEFAULT_GID 5000 - -namespace { -const mode_t PRIVATE_STORAGE_MODE = 0700; -} - -namespace Jobs { -namespace WidgetInstall { -TaskPrivateStorage::TaskPrivateStorage(InstallerContext& context) : - DPL::TaskDecl(this), - m_context(context) -{ - AddStep(&TaskPrivateStorage::StepCreateDirectory); -} - -void TaskPrivateStorage::StepCreateDirectory() -{ - using namespace WrtDB; - - LogInfo("Step: Creating private storage directory."); - - m_context.installStep = - InstallerContext::INSTALL_CREATE_PRIVATE_STORAGE; - - std::ostringstream widgetPath; - DPL::OptionalString pkgname = m_context.widgetConfig.pkgname; - if(!pkgname.IsNull()) { - widgetPath << m_context.locations->getPackageInstallationDir() << "/"; - } else { - ThrowMsg(Exceptions::InternalError, "No Package name exists."); - } - - if (euidaccess(widgetPath.str().c_str(), W_OK | X_OK) != 0) { - ThrowMsg(Exceptions::InternalError, DPL::GetErrnoString()); - } - - std::ostringstream storagePath; - storagePath << widgetPath.str().c_str() - << GlobalConfig::GetWidgetPrivateStoragePath(); - - if (euidaccess(storagePath.str().c_str(), F_OK) != 0) { - if(!WrtUtilMakeDir(storagePath.str(), PRIVATE_STORAGE_MODE)){ - LogError("Failed to create directory for private storage"); - ThrowMsg(Exceptions::InternalError, - "Failed to create directory for private storage"); - } - // '5000' is default uid, gid for applications. - // So installed applications should be launched as process of uid '5000'. - // the process can access private directory 'data' of itself. - if(chown(storagePath.str().c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Exceptions::InternalError, - "Chown to invaild user"); - } - } else if (euidaccess(storagePath.str().c_str(), W_OK | R_OK | X_OK) == 0) { - LogInfo("Private storage already exists."); - // Even if private directory already is created, private dircetory - // should change owner. - if(chown(storagePath.str().c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Exceptions::InternalError, - "Chown to invaild user"); - } - if(chmod(storagePath.str().c_str(), PRIVATE_STORAGE_MODE) != 0) { - ThrowMsg(Exceptions::InternalError, - "chmod to 0700"); - } - - } else { - ThrowMsg(Exceptions::InternalError, - "No access to private storage."); - } - - m_context.job->UpdateProgress( - InstallerContext::INSTALL_CREATE_PRIVATE_STORAGE, - "Private storage created." - ); -} -} //namespace WidgetInstall -} //namespace Jobs diff --git a/src/jobs/widget_install/task_recovery.cpp b/src/jobs/widget_install/task_recovery.cpp index 1b922db..bd844ae 100644 --- a/src/jobs/widget_install/task_recovery.cpp +++ b/src/jobs/widget_install/task_recovery.cpp @@ -72,10 +72,6 @@ void TaskRecovery::StepCreateCheckFile() m_context.installInfo = infoPath.str(); LogDebug("Create file : " << m_context.installInfo); - m_context.job->UpdateProgress( - InstallerContext::INSTALL_LINK_DEPENDS_DIRECTORY, - "depends directory linked." - ); } else { ThrowMsg(Exceptions::InternalError, "Fail to create file for recovery."); } diff --git a/src/jobs/widget_install/task_unzip.cpp b/src/jobs/widget_install/task_unzip.cpp index b19bc19..fb084f6 100644 --- a/src/jobs/widget_install/task_unzip.cpp +++ b/src/jobs/widget_install/task_unzip.cpp @@ -116,6 +116,10 @@ void TaskUnzip::StepUnzipPrepare() { ReThrowMsg(Exceptions::OpenZipFailed, m_installerContext.locations->getWidgetSource()); } + Catch(DPL::ZipInput::Exception::SeekFileFailed) + { + ThrowMsg(Exceptions::ExtractFileFailed,"m_installerContext.locations->getWidgetSource()"); + } } void TaskUnzip::StepUnzipProgress() diff --git a/src/jobs/widget_install/task_widget_config.cpp b/src/jobs/widget_install/task_widget_config.cpp index 8423144..bf5301a 100644 --- a/src/jobs/widget_install/task_widget_config.cpp +++ b/src/jobs/widget_install/task_widget_config.cpp @@ -80,13 +80,14 @@ TaskWidgetConfig::TaskWidgetConfig(InstallerContext& installContext) : AddStep(&TaskWidgetConfig::ProcessLocalizedStartFiles); AddStep(&TaskWidgetConfig::ProcessBackgroundPageFile); AddStep(&TaskWidgetConfig::ProcessLocalizedIcons); + AddStep(&TaskWidgetConfig::ProcessWidgetInstalledPath); AddStep(&TaskWidgetConfig::StepVerifyFeatures); + AddStep(&TaskWidgetConfig::StepCheckMinVersionInfo); if (!GlobalSettings::TestModeEnabled() && !m_installContext.m_quiet) { AddStep(&TaskWidgetConfig::StepCancelWidgetInstallationAfterVerifyFeatures); AddStep(&TaskWidgetConfig::StepShowWidgetInfo); AddStep(&TaskWidgetConfig::StepCancelWidgetInstallation); - AddStep(&TaskWidgetConfig::StepCheckMinVersionInfo); AddStep(&TaskWidgetConfig::StepCancelWidgetInstallationAfterMinVersion); AddStep(&TaskWidgetConfig::StepDeletePopupWin); } @@ -261,9 +262,9 @@ void TaskWidgetConfig::ProcessStartFile(const DPL::OptionalString& path, if (m_installContext.widgetConfig.webAppType == APP_TYPE_TIZENWEBAPP) { - const char *startPath = - DPL::ToUTF8String(startFileData.path).c_str(); - if (strstr(startPath, "http") == startPath) { + std::string startPath = DPL::ToUTF8String(startFileData.path); + + if (strstr(startPath.c_str(), "http") == startPath.c_str()) { WidgetRegisterInfo::StartFileProperties startFileProperties; if (!!type) { @@ -363,6 +364,13 @@ void TaskWidgetConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon) } } +void TaskWidgetConfig::ProcessWidgetInstalledPath() +{ + LogDebug("ProcessWidgetInstalledPath"); + m_installContext.widgetConfig.widgetInstalledPath = + DPL::FromUTF8String(m_installContext.locations->getPackageInstallationDir()); +} + void TaskWidgetConfig::StepCancelWidgetInstallationAfterVerifyFeatures() { LogDebug("StepCancelWidgetInstallationAfterVerifyFeatures"); @@ -426,8 +434,18 @@ void TaskWidgetConfig::StepCheckMinVersionInfo() if (!isMinVersionCompatible( m_installContext.widgetConfig.webAppType.appType, m_installContext.widgetConfig.minVersion)) { - std::string label = WIDGET_NOT_COMPATIBLE + QUESTION; - createInstallPopup(PopupType::WIDGET_MIN_VERSION, label); + if(!GlobalSettings::TestModeEnabled() && !m_installContext.m_quiet) + { + LogDebug("Platform version to low - launching"); + std::string label = WIDGET_NOT_COMPATIBLE + QUESTION; + createInstallPopup(PopupType::WIDGET_MIN_VERSION, label); + } + else + { + LogError("Platform version lower than required -> cancelling installation"); + ThrowMsg(Exceptions::NotAllowed, + "Platform version does not meet requirements"); + } } m_installContext.job->UpdateProgress( @@ -550,7 +568,9 @@ bool TaskWidgetConfig::isFeatureAllowed(WrtDB::AppType appType, LogInfo("FetureName = [" << featureName << "]"); AppType featureType = APP_TYPE_UNKNOWN; - const char* feature = DPL::ToUTF8String(featureName).c_str(); + 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 @@ -629,13 +649,15 @@ bool TaskWidgetConfig::isMinVersionCompatible(WrtDB::AppType appType, if (!parseVersionString(version, majorSupported, minorSupported, microSupported)) { - LogWarning("Invalid format of WAC version string."); + LogWarning("Invalid format of platform version string."); return true; } if (majorWidget > majorSupported || - minorWidget > minorSupported || - microWidget > microSupported) { + (majorWidget == majorSupported && minorWidget > minorSupported) || + (majorWidget == majorSupported && minorWidget == minorSupported + && microWidget > microSupported)) + { LogInfo("Platform doesn't support this widget."); return false; } diff --git a/src/jobs/widget_install/task_widget_config.h b/src/jobs/widget_install/task_widget_config.h index 740af5f..2b0b7dc 100755 --- a/src/jobs/widget_install/task_widget_config.h +++ b/src/jobs/widget_install/task_widget_config.h @@ -78,6 +78,7 @@ class TaskWidgetConfig : void ProcessBackgroundPageFile(); void ProcessLocalizedIcons(); void ProcessIcon(const WrtDB::ConfigParserData::Icon& icon); + void ProcessWidgetInstalledPath(); void StepVerifyFeatures(); void StepShowWidgetInfo(); void StepCheckMinVersionInfo(); diff --git a/src/jobs/widget_install/wac_security.cpp b/src/jobs/widget_install/wac_security.cpp index 4f81120..6dafd02 100644 --- a/src/jobs/widget_install/wac_security.cpp +++ b/src/jobs/widget_install/wac_security.cpp @@ -27,13 +27,6 @@ namespace Jobs { namespace WidgetInstall { void WacSecurity::getCertificateChainList( - WrtDB::CertificateChainList& list) const -{ - FOREACH(certIter, mCertificateChainList) - list.push_back(certIter->toBase64String()); -} - -void WacSecurity::getCertificateChainList( WrtDB::CertificateChainList& list, WrtDB::CertificateSource source) const { diff --git a/src/jobs/widget_install/wac_security.h b/src/jobs/widget_install/wac_security.h index e899ad8..a2095da 100644 --- a/src/jobs/widget_install/wac_security.h +++ b/src/jobs/widget_install/wac_security.h @@ -53,9 +53,6 @@ class WacSecurity : public WrtDB::IWacSecurity virtual bool isWacSigned() const { return mWacSigned; } virtual void getCertificateChainList( - WrtDB::CertificateChainList& list) const; - - virtual void getCertificateChainList( WrtDB::CertificateChainList& list, WrtDB::CertificateSource source) const; diff --git a/src/jobs/widget_install/widget_install_context.h b/src/jobs/widget_install/widget_install_context.h index 4fa010b..284cc1b 100755 --- a/src/jobs/widget_install/widget_install_context.h +++ b/src/jobs/widget_install/widget_install_context.h @@ -65,8 +65,6 @@ struct InstallerContext INSTALL_BACKUP_EXEC, /* For Update */ INSTALL_NEW_DB_INSERT, /* For Update */ - INSTALL_CREATE_PRIVATE_STORAGE, - INSTALL_LINK_DEPENDS_DIRECTORY, INSTALL_ACE_PREPARE, INSTALL_ACE_CHECK, INSTALL_SMACK_ENABLE, @@ -104,6 +102,7 @@ struct InstallerContext RequestedDevCapsMap staticPermittedDevCaps; std::string installInfo; /// bool m_quiet; + InstallLocationType locationType; }; #endif // INSTALLER_CONTEXT_H diff --git a/src/jobs/widget_install/widget_install_errors.h b/src/jobs/widget_install/widget_install_errors.h index 78480c2..109caff 100644 --- a/src/jobs/widget_install/widget_install_errors.h +++ b/src/jobs/widget_install/widget_install_errors.h @@ -47,8 +47,10 @@ enum Type ErrorDeferred, ///< Widget installation was deferred and will be continued when possible ErrorDatabaseFailure, ///< Failure in database ErrorRemovingFolderFailure, ///< Failure in removing existing widget folder + ErrorCreateVconfFailure, ///< Failure in creating vconf ErrorInstallOspServcie, ///< Failure in installing osp service ErrorUpdateWidget, ///< Failure in widget update. + ErrorInstallToExt, ///< Failure in install to sdcard ErrorUnknown ///< Temporary error. Try to not use this. }; @@ -80,9 +82,12 @@ DECLARE_JOB_EXCEPTION(Base, AlreadyInstalled, ErrorAlreadyInstalled) DECLARE_JOB_EXCEPTION(Base, UnknownError, ErrorUnknown) DECLARE_JOB_EXCEPTION(Base, DatabaseFailure, ErrorDatabaseFailure) DECLARE_JOB_EXCEPTION(Base, RemovingFolderFailure, ErrorRemovingFolderFailure) +DECLARE_JOB_EXCEPTION(Base, CreateVconfFailure, ErrorCreateVconfFailure) DECLARE_JOB_EXCEPTION(Base, CopyIconFailed, ErrorUnknown) +DECLARE_JOB_EXCEPTION(Base, ErrorExternalInstallingFailure, ErrorInstallToExt) + // Installation osp service DECLARE_JOB_EXCEPTION(Base, RequestInstallOspsvc, ErrorInstallOspServcie) DECLARE_JOB_EXCEPTION(Base, InstallOspsvcFailed, ErrorInstallOspServcie) diff --git a/src/jobs/widget_install/widget_installer_struct.h b/src/jobs/widget_install/widget_installer_struct.h index 2c7e3c8..2a655c8 100755 --- a/src/jobs/widget_install/widget_installer_struct.h +++ b/src/jobs/widget_install/widget_installer_struct.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include //Widget Installer typedefs @@ -71,7 +73,8 @@ enum Type ExistingVersionEqual | ExistingVersionNewer, - PolicyForceInstall = PolicyAlwaysInstall + PolicyForceInstall = PolicyAlwaysInstall, + PolicyDirectoryForceInstall }; inline Type operator | (const Type &a, @@ -100,10 +103,13 @@ struct WidgetInstallationStruct : public WidgetInstallCallbackBase { WidgetUpdateMode::Type updateMode; bool m_quiet; + bool m_preload; + std::shared_ptr pkgmgrInterface; // It must be empty-constructible as a parameter of generic event WidgetInstallationStruct() : updateMode(WidgetUpdateMode::Zero), - m_quiet(true) + m_quiet(true), + m_preload(false) { } @@ -111,10 +117,15 @@ struct WidgetInstallationStruct : public WidgetInstallCallbackBase InstallerProgressCallback progress, void *param, WidgetUpdateMode::Type mode, - bool quiet) : + bool quiet, + bool preload, + std::shared_ptr _pkgmgrInterface + ) : WidgetInstallCallbackBase(finished, progress, param), updateMode(mode), - m_quiet(quiet) + m_quiet(quiet), + m_preload(preload), + pkgmgrInterface(_pkgmgrInterface) { } }; diff --git a/src/jobs/widget_install/widget_unzip.cpp b/src/jobs/widget_install/widget_unzip.cpp deleted file mode 100644 index b8d0b98..0000000 --- a/src/jobs/widget_install/widget_unzip.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES 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 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace WrtDB; - -namespace { -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(std::string source, std::string path) : - m_source(source), - m_destPath(path) -{ - LogDebug("WidgetUnzip"); -} - -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::UnzipWidget() -{ - UnzipPrepare(); - UnzipProgress(); -} - -void WidgetUnzip::UnzipPrepare() -{ - LogInfo("Prepare to unzip..."); - - Try - { - m_zip.reset(new DPL::ZipInput(m_source)); - LogInfo("Widget package comment: " << m_zip->GetGlobalComment()); - - // Widget package must not be empty - if (m_zip->empty()) { - ThrowMsg(Exceptions::ZipEmpty, m_source); - } - - // Set iterator to first file - m_zipIterator = m_zip->begin(); - } - Catch(DPL::ZipInput::Exception::OpenFailed) - { - ReThrowMsg(Exceptions::OpenZipFailed, m_source); - } -} - -void WidgetUnzip::UnzipProgress() -{ - - // Show file info - LogInfo("Unzipping: '" << m_zipIterator->name << - "', Comment: '" << m_zipIterator->comment << - "', Compressed size: " << m_zipIterator->compressedSize << - ", Uncompressed size: " << m_zipIterator->uncompressedSize); - - - // Normalize file paths - // FIXME: Implement checking for invalid characters - - // Extract file or path - std::string fileName = m_zipIterator->name; - - if (fileName[fileName.size() - 1] == '/') { - // This is path - std::string newPath = m_destPath + "/" + - fileName.substr(0, fileName.size() - 1); - LogPedantic("Path to extract: " << newPath); - - // Create path in case of it is empty - createTempPath(newPath); - } else { - // This is regular file - std::string fileExtractPath = m_destPath + "/" + fileName; - - LogPedantic("File to extract: " << fileExtractPath); - - // Split into pat & file pair - PathAndFilePair pathAndFile = SplitFileAndPath(fileExtractPath); - - LogPedantic("Path and file: " << - pathAndFile.path << - " : " << pathAndFile.file); - - // First, ensure that path exists - createTempPath(pathAndFile.path); - - Try - { - // Open file - std::unique_ptr file( - m_zip->OpenFile(fileName)); - - // Extract single file - ExtractFile(file.get(), fileExtractPath); - } - Catch(DPL::ZipInput::Exception::OpenFileFailed) - { - ThrowMsg(Exceptions::ExtractFileFailed, fileName); - } - } - - // Check whether there are more files to extract - if (++m_zipIterator == m_zip->end()) { - LogInfo("Unzip progress finished successfuly"); - m_zip.reset(); - } else { - UnzipProgress(); - } -} - -void WidgetUnzip::UnzipDRMWidget() -{ - LogDebug("Decrypt drm widget"); - drm_trusted_sapps_decrypt_package_info_s package_info; - - strncpy(package_info.sadcf_filepath, m_source.c_str(), - sizeof(package_info.sadcf_filepath)); - strncpy(package_info.decrypt_filepath, m_destPath.c_str(), - sizeof(package_info.decrypt_filepath)); - - drm_trusted_request_type_e requestType = - DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE; - - int ret = drm_trusted_handle_request(requestType, - (void *)&package_info, NULL); - if (DRM_TRUSTED_RETURN_SUCCESS != ret) { - LogDebug("Failed unzip drm widget"); - ThrowMsg(Exceptions::ExtractFileFailed, m_destPath); - } -} -} //namespace WidgetInstall -} //namespace Jobs diff --git a/src/jobs/widget_install/widget_unzip.h b/src/jobs/widget_install/widget_unzip.h deleted file mode 100644 index 7c7b4ca..0000000 --- a/src/jobs/widget_install/widget_unzip.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES 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 INSTALLER_CORE_JOS_WIDGET_INSTALL_WIDGET_UNZIP_H -#define INSTALLER_CORE_JOS_WIDGET_INSTALL_WIDGET_UNZIP_H - -#include -#include - -#include - -class InstallerContext; - -namespace Jobs { -namespace WidgetInstall { -class WidgetUnzip -{ - private: - // Installation context - std::string m_source; - std::string m_destPath; - - // Unzip state - std::unique_ptr m_zip; - DPL::ZipInput::const_iterator m_zipIterator; - - void ExtractFile(DPL::ZipInput::File *input, - const std::string &destFileName); - - void UnzipPrepare(); - void UnzipProgress(); - - public: - WidgetUnzip(std::string m_source, std::string m_destPath); - void UnzipWidget(); - void UnzipDRMWidget(); -}; -} //namespace WidgetInstall -} //namespace Jobs - -#endif // INSTALLER_CORE_JOS_WIDGET_INSTALL_WIDGET_UNZIP_H diff --git a/src/jobs/widget_uninstall/job_widget_uninstall.cpp b/src/jobs/widget_uninstall/job_widget_uninstall.cpp index 392106f..e6153ff 100644 --- a/src/jobs/widget_uninstall/job_widget_uninstall.cpp +++ b/src/jobs/widget_uninstall/job_widget_uninstall.cpp @@ -23,6 +23,7 @@ #include #include #include +#include using namespace WrtDB; @@ -66,6 +67,7 @@ JobWidgetUninstall::JobWidgetUninstall(const std::string & widgetPkgName, m_context.uninstallStep = UninstallerContext::UNINSTALL_START; m_context.job = this; m_context.pkgname = widgetPkgName; + m_context.isExternalWidget = getExternalWidgetFlag(); Try { @@ -85,8 +87,8 @@ JobWidgetUninstall::JobWidgetUninstall(const std::string & widgetPkgName, AddTask(new TaskDeleteCertificates(m_context)); // send start signal of pkgmgr - if (PkgmgrSignalSingleton::Instance().setPkgname(m_context.pkgname)) { - PkgmgrSignalSingleton::Instance().sendSignal( + if (getInstallerStruct().pkgmgrInterface->setPkgname(m_context.pkgname)) { + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_START_KEY, PKGMGR_START_UNINSTALL); } @@ -121,7 +123,7 @@ void JobWidgetUninstall::SendProgress() // send progress signal of pkgmgr std::ostringstream percent; percent << static_cast(GetProgressPercent()); - PkgmgrSignalSingleton::Instance().sendSignal( + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_PROGRESS_KEY, percent.str()); @@ -137,7 +139,7 @@ void JobWidgetUninstall::SendFinishedSuccess() { using namespace PackageManager; // send signal of pkgmgr - PkgmgrSignalSingleton::Instance().sendSignal( + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_END_KEY, PKGMGR_END_SUCCESS); @@ -153,7 +155,7 @@ void JobWidgetUninstall::SendFinishedFailure() LogError("Message: " << m_exceptionMessage); // send signal of pkgmgr - PkgmgrSignalSingleton::Instance().sendSignal( + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_END_KEY, PKGMGR_END_FAILURE); @@ -168,5 +170,17 @@ void JobWidgetUninstall::SaveExceptionData(const Jobs::JobExceptionBase &e) m_exceptionCaught = static_cast(e.getParam()); m_exceptionMessage = e.GetMessage(); } + +bool JobWidgetUninstall::getExternalWidgetFlag() const +{ + + LogDebug("Get external widget"); + if (APP2EXT_SD_CARD == app2ext_get_app_location(m_context.pkgname.c_str())) { + LogDebug("This widget is in external stroage"); + return true; + } + return false; +} + } //namespace WidgetUninstall } //namespace Jobs diff --git a/src/jobs/widget_uninstall/job_widget_uninstall.h b/src/jobs/widget_uninstall/job_widget_uninstall.h index 98cd62c..80c188c 100644 --- a/src/jobs/widget_uninstall/job_widget_uninstall.h +++ b/src/jobs/widget_uninstall/job_widget_uninstall.h @@ -55,6 +55,7 @@ class JobWidgetUninstall : std::string getRemovedTizenId() const; bool getRemoveStartedFlag() const; bool getRemoveFinishedFlag() const; + bool getExternalWidgetFlag() const; void SendProgress(); void SendFinishedSuccess(); diff --git a/src/jobs/widget_uninstall/task_db_update.cpp b/src/jobs/widget_uninstall/task_db_update.cpp index b18feb0..d3f2c93 100644 --- a/src/jobs/widget_uninstall/task_db_update.cpp +++ b/src/jobs/widget_uninstall/task_db_update.cpp @@ -23,8 +23,11 @@ #include #include #include +#include +#include #include +#include using namespace WrtDB; @@ -45,6 +48,9 @@ void TaskDbUpdate::StepDbUpdate() { Try { + //TODO: widget handle should not be used any more + ace_unregister_widget(static_cast( + WidgetDAOReadOnly::getHandle(m_context.locations->getPkgname()))); WidgetDAO::unregisterWidget(m_context.locations->getPkgname()); LogDebug("Unregistered widget successfully!"); diff --git a/src/jobs/widget_uninstall/task_remove_files.cpp b/src/jobs/widget_uninstall/task_remove_files.cpp index 2dfe92e..d7c3157 100644 --- a/src/jobs/widget_uninstall/task_remove_files.cpp +++ b/src/jobs/widget_uninstall/task_remove_files.cpp @@ -25,24 +25,38 @@ #include #include #include +#include #include #include #include #include +#include +#include +#include +#include namespace Jobs { namespace WidgetUninstall { using namespace WrtDB; +namespace { +const char * const VCONF_KEY_PREFIX = "file/private/"; +} + TaskRemoveFiles::TaskRemoveFiles(UninstallerContext& context) : DPL::TaskDecl(this), m_context(context) { - AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory); + if (!m_context.isExternalWidget) { + AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory); + } else { + AddStep(&TaskRemoveFiles::StepRemoveExternalWidget); + } //AddStep(&TaskRemoveFiles::StepRemoveDesktop); AddStep(&TaskRemoveFiles::StepRemoveManifest); AddStep(&TaskRemoveFiles::StepRemoveExternalLocations); + AddStep(&TaskRemoveFiles::StepRemoveVconf); AddStep(&TaskRemoveFiles::StepRemoveFinished); } @@ -60,6 +74,10 @@ void TaskRemoveFiles::StepRemoveInstallationDirectory() if(!WrtUtilRemove(widgetDir)){ LogWarning("Removing widget installation directory failed"); } + std::string dataDir = m_context.locations->getUserDataRootDir(); + if(!WrtUtilRemove(dataDir)){ + LogWarning(dataDir + " is already removed"); + } m_context.job->UpdateProgress( UninstallerContext::UNINSTALL_REMOVE_WIDGETDIR, "Widget INstallation Directory Removal Finished"); @@ -138,7 +156,10 @@ void TaskRemoveFiles::StepRemoveExternalLocations() if(WrtUtilFileExists(*path)) { LogDebug(" -> " << *path); - remove(path->c_str()); + int ret = remove(path->c_str()); + if (ret != 0) { + LogError("Failed to remove the file: " << path->c_str() << " with error: " << strerror(errno)); + } } else if(WrtUtilDirExists(*path)) { @@ -155,5 +176,30 @@ void TaskRemoveFiles::StepRemoveExternalLocations() dao.unregisterAllExternalLocations(); } +void TaskRemoveFiles::StepRemoveVconf() +{ + std::string key = + WrtDB::VconfConfig::GetVconfKeyRootPath( + m_context.locations->getPkgname()); + if(vconf_unset_recursive(key.c_str())) { + LogError("Fail to unset vconf file"); + } else { + LogDebug("vconf file is removed"); + } +} + +void TaskRemoveFiles::StepRemoveExternalWidget() +{ + Try { + WidgetInstallToExtSingleton::Instance().initialize(m_context.pkgname); + WidgetInstallToExtSingleton::Instance().uninstallation(); + WidgetInstallToExtSingleton::Instance().deinitialize(); + } + Catch (WidgetInstallToExt::Exception::ErrorInstallToExt) + { + Throw(Jobs::WidgetUninstall::TaskRemoveFiles::Exception::RemoveFilesFailed); + } +} + } //namespace WidgetUninstall } //namespace Jobs diff --git a/src/jobs/widget_uninstall/task_remove_files.h b/src/jobs/widget_uninstall/task_remove_files.h index 6959242..0336443 100644 --- a/src/jobs/widget_uninstall/task_remove_files.h +++ b/src/jobs/widget_uninstall/task_remove_files.h @@ -51,6 +51,8 @@ class TaskRemoveFiles : void StepRemoveDesktop(); void StepRemoveManifest(); void StepRemoveExternalLocations(); + void StepRemoveVconf(); + void StepRemoveExternalWidget(); public: explicit TaskRemoveFiles(UninstallerContext& context); diff --git a/src/jobs/widget_uninstall/uninstaller_context.h b/src/jobs/widget_uninstall/uninstaller_context.h index 1aeb086..caedcb7 100644 --- a/src/jobs/widget_uninstall/uninstaller_context.h +++ b/src/jobs/widget_uninstall/uninstaller_context.h @@ -60,6 +60,7 @@ struct UninstallerContext UninstallStep uninstallStep; ///< current step of installation Jobs::WidgetUninstall::JobWidgetUninstall *job; std::string pkgname; + bool isExternalWidget; }; #endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_ diff --git a/src/jobs/widget_uninstall/widget_uninstaller_struct.h b/src/jobs/widget_uninstall/widget_uninstaller_struct.h index 4388164..ce2d4cc 100644 --- a/src/jobs/widget_uninstall/widget_uninstaller_struct.h +++ b/src/jobs/widget_uninstall/widget_uninstaller_struct.h @@ -29,6 +29,8 @@ #include #include #include +#include +#include //Widget Uninstaller typedefs typedef void (*UninstallerFinishedCallback)( @@ -44,6 +46,26 @@ typedef void (*UninstallerProgressCallback)( //UninstallationStruct typedef Jobs::JobCallbacksBase -WidgetUninstallationStruct; +WidgetUninstallCallbackBase; + +struct WidgetUninstallationStruct : public WidgetUninstallCallbackBase +{ + std::shared_ptr pkgmgrInterface; + + // It must be empty-constructible as a parameter of generic event + WidgetUninstallationStruct() + { + } + + WidgetUninstallationStruct(UninstallerFinishedCallback finished, + UninstallerProgressCallback progress, + void *param, + std::shared_ptr _pkgmgrInterface + ) : + WidgetUninstallCallbackBase(finished, progress, param), + pkgmgrInterface(_pkgmgrInterface) + { + } +}; #endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_WIDGET_INSTALLER_STRUCT_H_ diff --git a/src/logic/installer_controller.h b/src/logic/installer_controller.h index 938e7ee..55c68fe 100644 --- a/src/logic/installer_controller.h +++ b/src/logic/installer_controller.h @@ -52,7 +52,7 @@ DECLARE_GENERIC_EVENT_2(InstallPluginEvent, std::string, PluginInstallerStruct) /** * @brief Event for inicietig widget uninstallation. * - * WidgetHandler is used to point witch widget shuld be uninstalled + * tizen id is used to point witch widget shuld be uninstalled */ DECLARE_GENERIC_EVENT_2(UninstallWidgetEvent, std::string, diff --git a/src/misc/widget_install_to_external.cpp b/src/misc/widget_install_to_external.cpp new file mode 100644 index 0000000..3751d60 --- /dev/null +++ b/src/misc/widget_install_to_external.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 +#include +#include + +IMPLEMENT_SAFE_SINGLETON(WidgetInstallToExt) + +WidgetInstallToExt::WidgetInstallToExt() : + m_handle(NULL), + m_appId("") +{ +} + +WidgetInstallToExt::~WidgetInstallToExt() +{ +} + +void WidgetInstallToExt::initialize(std::string appId) +{ + LogDebug("WidgetInstallToExt::initialize()"); + m_appId = appId; + + m_handle = app2ext_init(APP2EXT_SD_CARD); + if (NULL == m_handle) { + ThrowMsg(Exception::ErrorInstallToExt, "initialize failed"); + } +} + +void WidgetInstallToExt::deinitialize() +{ + LogDebug("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) +{ + LogDebug("WidgetInstallToExt::preInstallation()"); + Assert(m_handle); + + int ret = m_handle->interface.pre_install(m_appId.c_str(), dirList, dSize); + + if (APP2EXT_SUCCESS == ret ) { + LogDebug("App2Ext pre install success"); + } else { + postInstallation(false); + ThrowMsg(Exception::ErrorInstallToExt, "pre-install failed"); + } +} + +void WidgetInstallToExt::postInstallation(bool status) +{ + LogDebug("WidgetInstallToExt::postInstallation()"); + Assert(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) +{ + LogDebug("WidgetInstallToExt::preUpgrade()"); + Assert(m_handle); + + int ret = m_handle->interface.pre_upgrade(m_appId.c_str(), dirList, dSize); + if (APP2EXT_SUCCESS == ret ) { + LogDebug("App2Ext pre-upgrade success"); + } else { + postUpgrade(false); + ThrowMsg(Exception::ErrorInstallToExt, "pre-upgrade failed"); + } +} + +void WidgetInstallToExt::postUpgrade(bool status) +{ + LogDebug("WidgetInstallToExt::postUpgrade()"); + Assert(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() +{ + LogDebug("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())) { + LogDebug("App2Ext pre-uninstall success"); + } else { + ThrowMsg(Exception::ErrorInstallToExt, "post-uninstall failed"); + } + } else { + ThrowMsg(Exception::ErrorInstallToExt, "pre-uninstall failed"); + } +} diff --git a/src/misc/widget_install_to_external.h b/src/misc/widget_install_to_external.h new file mode 100644 index 0000000..9f71906 --- /dev/null +++ b/src/misc/widget_install_to_external.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @file 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 +#include +#include +#include + + +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(); + +private: + app2ext_handle *m_handle; + std::string m_appId; + + WidgetInstallToExt(); + ~WidgetInstallToExt(); + + friend class DPL::Singleton; +}; + +typedef DPL::Singleton WidgetInstallToExtSingleton; + +#endif // WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H diff --git a/src/misc/widget_location.cpp b/src/misc/widget_location.cpp index b899bec..35a8026 100644 --- a/src/misc/widget_location.cpp +++ b/src/misc/widget_location.cpp @@ -42,7 +42,9 @@ WidgetLocation::DirectoryDeletor::DirectoryDeletor(std::string tempPath) WidgetLocation::DirectoryDeletor::~DirectoryDeletor() { LogDebug("Removing widget installation temporary directory: " << m_dirpath.c_str()); - WrtUtilRemove(m_dirpath); + if(!WrtUtilRemove(m_dirpath)){ + LogError("Fail at removing directory: " << m_dirpath.c_str()); + } } std::string WidgetLocation::DirectoryDeletor::getTempPath() const @@ -65,47 +67,58 @@ WidgetLocation::~WidgetLocation() WidgetLocation::WidgetLocation(const std::string & widgetname, std::string sourcePath, - WrtDB::PackagingType t): + WrtDB::PackagingType t, + InstallLocationType locationType): m_pkgname(widgetname), m_widgetSource(sourcePath), m_type(t), m_temp(new WidgetLocation::DirectoryDeletor()) { + if (INSTALL_LOCATION_TYPE_PRELOAD == locationType) { + m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath(); + } else { + m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); + } } WidgetLocation::WidgetLocation(const std::string & widgetname, std::string sourcePath, std::string dirPath, - WrtDB::PackagingType t): + WrtDB::PackagingType t, + InstallLocationType locationType): m_pkgname(widgetname), m_widgetSource(sourcePath), m_type(t), m_temp(new WidgetLocation::DirectoryDeletor(dirPath)) { + if (INSTALL_LOCATION_TYPE_PRELOAD == locationType) { + m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath(); + } else { + m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); + } } // TODO cache all these paths std::string WidgetLocation::getInstallationDir() const { - return std::string(WrtDB::GlobalConfig::GetUserInstalledWidgetPath()); + return m_installedPath; } std::string WidgetLocation::getPackageInstallationDir() const { - return std::string(WrtDB::GlobalConfig::GetUserInstalledWidgetPath()) + "/" - + m_pkgname; + return m_installedPath + "/" + m_pkgname; } std::string WidgetLocation::getSourceDir() const { - return std::string(WrtDB::GlobalConfig::GetUserInstalledWidgetPath()) + "/" + return m_installedPath + "/" + m_pkgname + WrtDB::GlobalConfig::GetWidgetSrcPath(); } std::string WidgetLocation::getBinaryDir() const { - return std::string(WrtDB::GlobalConfig::GetUserInstalledWidgetPath()) + "/" + return m_installedPath + "/" + m_pkgname + WrtDB::GlobalConfig::GetUserWidgetExecPath(); } @@ -134,6 +147,24 @@ std::string WidgetLocation::getBackupExecFile() const return getBackupBinaryDir() + "/" + m_pkgname; } +std::string WidgetLocation::getUserDataRootDir() const +{ + return std::string(WrtDB::GlobalConfig::GetWidgetUserDataPath()) + + "/" + m_pkgname; +} + +std::string WidgetLocation::getPrivateStorageDir() const +{ + return getUserDataRootDir() + "/" + + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath(); +} + +std::string WidgetLocation::getShareDir() const +{ + return std::string(WrtDB::GlobalConfig::GetUserInstalledWidgetPath()) + "/" + + m_pkgname + "/" + WrtDB::GlobalConfig::GetWidgetSharePath(); +} + std::string WidgetLocation::getTemporaryPackageDir() const { return m_temp->getTempPath(); @@ -141,6 +172,9 @@ std::string WidgetLocation::getTemporaryPackageDir() const std::string WidgetLocation::getTemporaryRootDir() const { + if (m_type == WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) { + return getWidgetSource(); + } if(m_type == WrtDB::PKG_TYPE_HYBRID_WEB_APP) { return getTemporaryPackageDir() + WrtDB::GlobalConfig::GetWidgetSrcPath(); @@ -153,7 +187,7 @@ std::string WidgetLocation::getTemporaryRootDir() const std::string WidgetLocation::getConfigurationDir() const { - if(m_type == WrtDB::PKG_TYPE_HOSTED_WEB_APP) + if(m_type == WrtDB::PKG_TYPE_HOSTED_WEB_APP) { std::string path = "."; int index = m_widgetSource.find_last_of("\\/"); @@ -163,7 +197,10 @@ std::string WidgetLocation::getConfigurationDir() const } return path; } - else + else if (m_type == WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + { + return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath(); + } else { return getTemporaryRootDir(); } diff --git a/src/misc/widget_location.h b/src/misc/widget_location.h index ab9fa29..e04c3dd 100644 --- a/src/misc/widget_location.h +++ b/src/misc/widget_location.h @@ -25,6 +25,7 @@ #include #include +#include /** * @brief The WidgetLocation class @@ -36,6 +37,7 @@ * * /opt/apps/[package_name] * \_____________ /data + * \_____________ /share * \_____________ /bin * \_____________ /bin/[id_of_installed_package] * \_____________ /res/wgt/ @@ -91,15 +93,20 @@ public: * In destruction removes temporary directory */ WidgetLocation(const std::string & widgetname, std::string sourcePath, - WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP); + WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP, + InstallLocationType ltype = + INSTALL_LOCATION_TYPE_NOMAL); WidgetLocation(const std::string & widgetname, std::string sourcePath, std::string dirPath, - WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP); + WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP, + InstallLocationType ltype = + INSTALL_LOCATION_TYPE_NOMAL); + ~WidgetLocation(); // Installed paths - std::string getInstallationDir() const; // /opt/apps + 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 @@ -108,6 +115,9 @@ public: std::string getBackupSourceDir() const; // /opt/apps/[package]/backup/res/wgt std::string getBackupBinaryDir() const; // /opt/apps/[package]/backup/bin std::string getBackupExecFile() const; // /opt/apps/[package]/backup/bin/[package] + std::string getUserDataRootDir() const; // /opt/usr/apps/[package] + std::string getPrivateStorageDir() const; // /opt/usr/apps/[package]/data + std::string getShareDir() const; // /opt/usr/apps/[package]/share // Temporary paths /** @@ -185,6 +195,7 @@ private: WrtDB::PackagingType m_type; std::shared_ptr m_temp; //directory WrtDB::ExternalLocationList m_externals; + std::string m_installedPath; }; #endif // WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H diff --git a/src/pkg-manager/pkgmgr_signal.cpp b/src/pkg-manager/pkgmgr_signal.cpp index 13b32b5..4b48b83 100644 --- a/src/pkg-manager/pkgmgr_signal.cpp +++ b/src/pkg-manager/pkgmgr_signal.cpp @@ -19,12 +19,10 @@ * @brief */ -#include #include #include #include -IMPLEMENT_SAFE_SINGLETON(PackageManager::PkgmgrSignal) namespace PackageManager { @@ -95,7 +93,7 @@ bool PkgmgrSignal::deinitialize() return true; } -bool PkgmgrSignal::setPkgname(std::string name) +bool PkgmgrSignal::setPkgname(const std::string& name) { if (!m_initialized) { @@ -115,7 +113,7 @@ bool PkgmgrSignal::setPkgname(std::string name) return true; } -bool PkgmgrSignal::sendSignal(std::string key, std::string value) const +bool PkgmgrSignal::sendSignal(const std::string& key, const std::string& value) const { if (!m_initialized) { diff --git a/src/pkg-manager/pkgmgr_signal.h b/src/pkg-manager/pkgmgr_signal.h index 6c4e043..a939c50 100644 --- a/src/pkg-manager/pkgmgr_signal.h +++ b/src/pkg-manager/pkgmgr_signal.h @@ -15,14 +15,15 @@ */ /* * @author Yunchan Cho (yunchan.cho@samsung.com) - * @version 0.1 + * @author Jan Olszak (j.olszak@samsung.com) + * @version 0.2 * @brief */ #ifndef WRT_PKGMGR_SIGNAL_H_ #define WRT_PKGMGR_SINGAL_H_ -#include +#include #include namespace PackageManager{ @@ -38,17 +39,20 @@ namespace PackageManager{ typedef pkgmgr_installer* PkgmgrHandle; -class PkgmgrSignal +class PkgmgrSignal: public IPkgmgrSignal { public: bool initialize(int argc, char* argv[]); bool deinitialize(); - bool setPkgname(std::string name); - bool sendSignal(std::string key, std::string value) const; + bool setPkgname(const std::string& name); + bool sendSignal(const std::string& key, const std::string& value) const; std::string getPkgname() const; int getRequestedType() const; bool isNoPopupRequired() const; + PkgmgrSignal(); + virtual ~PkgmgrSignal(); + private: bool m_initialized; PkgmgrHandle m_handle; @@ -56,15 +60,7 @@ class PkgmgrSignal std::string m_pkgname; bool m_noPopup; int m_reqType; - - PkgmgrSignal(); - ~PkgmgrSignal(); - - friend class DPL::Singleton; }; - -typedef DPL::Singleton PkgmgrSignalSingleton; - } // PackageManager #endif // WRT_PKGMGR_SIGNAL_H_ diff --git a/src/pkg-manager/pkgmgr_signal_dummy.h b/src/pkg-manager/pkgmgr_signal_dummy.h new file mode 100644 index 0000000..f8862ee --- /dev/null +++ b/src/pkg-manager/pkgmgr_signal_dummy.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * @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 + +namespace PackageManager { + +class PkgmgrSignalDummy: public IPkgmgrSignal +{ +public: + PkgmgrSignalDummy() + { + } + + virtual ~PkgmgrSignalDummy() + { + } + bool setPkgname(const std::string& name) + { + return false; + } + + bool sendSignal(const std::string& key, const std::string& value) const + { + return false; + } + + std::string getPkgname() const + { + return ""; + } +}; + +} // PkgmgrSignalDummy + +#endif // WRT_PKGMGR_SIGNAL_DUMMY_H_ diff --git a/src/jobs/widget_install/task_private_storage.h b/src/pkg-manager/pkgmgr_signal_interface.h similarity index 50% rename from src/jobs/widget_install/task_private_storage.h rename to src/pkg-manager/pkgmgr_signal_interface.h index e919f6b..187efb5 100644 --- a/src/jobs/widget_install/task_private_storage.h +++ b/src/pkg-manager/pkgmgr_signal_interface.h @@ -13,33 +13,27 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @file task_private_storage.h - * @author Zbigniew Kostrzewa (z.kostrzewa@samsung.com) - * @version 1.0 - * @brief Header file for installer task private storage. +/* + * @author Jan Olszak (j.olszak@samsung.com) + * @version 0.1 + * @brief Interface for PkgmgrSignal. */ -#ifndef INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PRIVATESTORAGE_H -#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_PRIVATESTORAGE_H -#include +#ifndef WRT_PKGMGR_SIGNAL_INTERFACE_H_ +#define WRT_PKGMGR_SIGNAL_INTERFACE_H_ -class InstallerContext; +#include +namespace PackageManager { -namespace Jobs { -namespace WidgetInstall { -class TaskPrivateStorage : public DPL::TaskDecl +class IPkgmgrSignal { - public: - explicit TaskPrivateStorage(InstallerContext& context); - - private: - void StepCreateDirectory(); - - private: - InstallerContext& m_context; +public: + virtual bool setPkgname(const std::string& name) = 0; + virtual bool sendSignal(const std::string& key, const std::string& value) const = 0; + virtual std::string getPkgname() const = 0; + virtual ~IPkgmgrSignal(){}; }; -} //namespace WidgetInstall -} //namespace Jobs -#endif +} // IPkgmgrSignal + +#endif // WRT_PKGMGR_SIGNAL_INTERFACE_H_ diff --git a/src/wrt-installer/wrt_installer.cpp b/src/wrt-installer/wrt_installer.cpp index 354cb5a..425d655 100644 --- a/src/wrt-installer/wrt_installer.cpp +++ b/src/wrt-installer/wrt_installer.cpp @@ -49,7 +49,8 @@ #include #include #include -#include + + #define NOFILE_CNT_FOR_INSTALLER 9999 @@ -89,7 +90,8 @@ WrtInstaller::WrtInstaller(int argc, char **argv) : m_installByPkgmgr(false), m_quiet(true), m_popup(NULL), - m_startupPluginInstallation(false) + m_startupPluginInstallation(false), + m_preloadWidget(false) { Touch(); LogDebug("App Created"); @@ -113,6 +115,12 @@ void WrtInstaller::OnCreate() std::string arg = m_argv[0]; + pkgmgrSignalInterface = std::static_pointer_cast( + std::shared_ptr( + new PackageManager::PkgmgrSignalDummy() + ) + ); + if (arg.empty()) { return showHelpAndQuit(); } @@ -147,8 +155,17 @@ void WrtInstaller::OnCreate() return showHelpAndQuit(); } + struct stat info; + if (-1 != stat(m_argv[2], &info) && S_ISDIR(info.st_mode)) { + LogInfo("Installing package directly from directory"); + m_installPolicy = WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL; + } + else + { + LogInfo("Installing from regular location"); + m_installPolicy = WRT_WIM_POLICY_WAC; + } m_packagePath = m_argv[2]; - m_installPolicy = WRT_WIM_POLICY_WAC; AddStep(&WrtInstaller::installStep); } else if (arg == "-if" || arg == "--install-force") { if (m_argc != 3) { @@ -158,6 +175,15 @@ void WrtInstaller::OnCreate() m_packagePath = m_argv[2]; m_installPolicy = WRT_WIM_POLICY_FORCE_INSTALL; AddStep(&WrtInstaller::installStep); + } else if (arg == "-il" || arg == "--install-preload") { + if (m_argc != 3) { + return showHelpAndQuit(); + } + + m_packagePath = m_argv[2]; + m_preloadWidget = true; + m_installPolicy = WRT_WIM_POLICY_WAC; + AddStep(&WrtInstaller::installStep); } else if (arg == "-un" || arg == "--uninstall-name") { if (m_argc != 3) { return showHelpAndQuit(); @@ -184,16 +210,31 @@ void WrtInstaller::OnCreate() using namespace PackageManager; m_installByPkgmgr = true; - PkgmgrSignalSingleton::Instance().initialize(m_argc, m_argv); - m_quiet = PkgmgrSignalSingleton::Instance().isNoPopupRequired(); + auto pkgmgrSignal = std::shared_ptr( + new PackageManager::PkgmgrSignal() + ); + + pkgmgrSignal->initialize(m_argc, m_argv); + m_quiet = pkgmgrSignal->isNoPopupRequired(); LogDebug("backend m_quiet"<getRequestedType(); + pkgmgrSignalInterface = + std::static_pointer_cast(pkgmgrSignal); switch (reqType) { case PKGMGR_REQ_INSTALL: m_packagePath = m_argv[4]; - m_installPolicy = WRT_WIM_POLICY_WAC; + struct stat info; + if (-1 != stat(m_argv[4], &info) && S_ISDIR(info.st_mode)) { + LogInfo("Installing package directly from directory"); + m_installPolicy = WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL; + } + else + { + LogInfo("Installing from regular location"); + m_installPolicy = WRT_WIM_POLICY_WAC; + } AddStep(&WrtInstaller::installStep); break; case PKGMGR_REQ_UNINSTALL: @@ -324,7 +365,9 @@ void WrtInstaller::installStep() (!m_quiet || m_installByPkgmgr) ? &staticWrtInstallProgressCallback : NULL, m_installPolicy, - m_quiet); + m_quiet, + m_preloadWidget, + pkgmgrSignalInterface); } void WrtInstaller::installPluginsStep() @@ -405,7 +448,8 @@ void WrtInstaller::uninstallPkgNameStep() LogDebug("Package name : " << m_name); wrt_uninstall_widget(m_name.c_str(), this, &staticWrtStatusCallback, (!m_quiet || m_installByPkgmgr) - ? &staticWrtUninstallProgressCallback : NULL); + ? &staticWrtUninstallProgressCallback : NULL, + pkgmgrSignalInterface); } void WrtInstaller::uninstallGuidStep() @@ -416,7 +460,8 @@ void WrtInstaller::uninstallGuidStep() if (status == WRT_SUCCESS) { LogDebug("Guid : " << m_name); wrt_uninstall_widget(pkgname.c_str(), this, &staticWrtStatusCallback, - !m_quiet ? &staticWrtUninstallProgressCallback : NULL); + !m_quiet ? &staticWrtUninstallProgressCallback : NULL, + pkgmgrSignalInterface); } else { printf("failed: can not uninstall widget\n"); LogError("Fail to uninstalling widget... "); @@ -463,7 +508,8 @@ void WrtInstaller::unistallWgtFileStep() if (status == WRT_SUCCESS) { LogDebug("Pkgname from packagePath : " << pkgname); wrt_uninstall_widget(pkgname.c_str(), this, &staticWrtStatusCallback, - !m_quiet ? &staticWrtUninstallProgressCallback : NULL); + !m_quiet ? &staticWrtUninstallProgressCallback : NULL, + pkgmgrSignalInterface); } else { LogError("Fail to uninstalling widget... "); m_returnStatus = -1; @@ -906,44 +952,48 @@ bool WrtInstaller::popupsEnabled() const int main(int argc, char *argv[]) { - // Output on stdout will be flushed after every newline character, - // even if it is redirected to a pipe. This is useful for running - // from a script and parsing output. - // (Standard behavior of stdlib is to use full buffering when - // redirected to a pipe, which means even after an end of line - // the output may not be flushed). - setlinebuf(stdout); - - // Check and re-set the file open limitation - struct rlimit rlim; - if (getrlimit(RLIMIT_NOFILE, &rlim) != -1) { - LogDebug("RLIMIT_NOFILE sft(" << rlim.rlim_cur << ")" ); - LogDebug("RLIMIT_NOFILE hrd(" << 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) { - LogError("setrlimit is fail!!"); + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + // 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) { + LogDebug("RLIMIT_NOFILE sft(" << rlim.rlim_cur << ")" ); + LogDebug("RLIMIT_NOFILE hrd(" << 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) { + LogError("setrlimit is fail!!"); + } } + } else { + LogError("getrlimit is fail!!"); } - } else { - LogError("getrlimit is fail!!"); - } - // set evas backend type for emulator - // popup isn't showed in the emulator, - // if backend isn't set to SW backend - if (GlobalSettings::IsEmulator()) { - if (setenv("ELM_ENGINE", "x11", 1)) { - LogDebug("Enable backend"); + // set evas backend type for emulator + // popup isn't showed in the emulator, + // if backend isn't set to SW backend + if (GlobalSettings::IsEmulator()) { + if (setenv("ELM_ENGINE", "x11", 1)) { + LogDebug("Enable backend"); + } } - } - WrtInstaller app(argc, argv); - int ret = app.Exec(); - LogDebug("App returned: " << ret); - ret = app.getReturnStatus(); - LogDebug("WrtInstaller returned: " << ret); - return ret; + WrtInstaller app(argc, argv); + int ret = app.Exec(); + LogDebug("App returned: " << ret); + ret = app.getReturnStatus(); + LogDebug("WrtInstaller returned: " << ret); + return ret; + } + UNHANDLED_EXCEPTION_HANDLER_END } diff --git a/src/wrt-installer/wrt_installer.h b/src/wrt-installer/wrt_installer.h index d6e2315..723236f 100644 --- a/src/wrt-installer/wrt_installer.h +++ b/src/wrt-installer/wrt_installer.h @@ -31,7 +31,11 @@ #include #include #include -#include + +#include +#include +#include +#include namespace WRTInstallerNS { //anonymous DECLARE_GENERIC_EVENT_0(QuitEvent) @@ -134,6 +138,7 @@ class WrtInstaller : bool popupsEnabled() const; // Private data + std::shared_ptr pkgmgrSignalInterface; wrt_widget_install_mode_e m_installPolicy; std::string m_bundleValue; std::string m_packagePath; @@ -149,6 +154,7 @@ class WrtInstaller : bool m_startupPluginInstallation; std::string m_webAppConfig; std::string m_webAppIcon; + bool m_preloadWidget; typedef std::list PluginPathList; DPL::Optional m_pluginsPaths; diff --git a/src/wrt-installer/wrt_installer_api.cpp b/src/wrt-installer/wrt_installer_api.cpp index 21fcc72..d643991 100755 --- a/src/wrt-installer/wrt_installer_api.cpp +++ b/src/wrt-installer/wrt_installer_api.cpp @@ -62,8 +62,10 @@ extern "C" inline WidgetUpdateMode::Type translateWidgetUpdateMode( wrt_widget_update_mode_t updateMode) { - WidgetUpdateMode::Type result = WidgetUpdateMode::Zero; + if (updateMode == WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL) + return WidgetUpdateMode::PolicyDirectoryForceInstall; + WidgetUpdateMode::Type result = WidgetUpdateMode::Zero; if (updateMode & WRT_WIM_NOT_INSTALLED) { result = result | WidgetUpdateMode::NotInstalled; } @@ -136,17 +138,17 @@ extern "C" "> does not exist."); } - if_ok &= (checkPath(GlobalConfig::GetFactoryInstalledWidgetPath())); + if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath())); if (!if_ok) { LogError( - "Path <" << GlobalConfig::GetFactoryInstalledWidgetPath() << + "Path <" << GlobalConfig::GetUserInstalledWidgetPath() << "> does not exist."); } - if_ok &= (checkPath(GlobalConfig::GetUserInstalledWidgetPath())); + if_ok &= (checkPath(GlobalConfig::GetUserPreloadedWidgetPath())); if (!if_ok) { LogError( - "Path <" << GlobalConfig::GetUserInstalledWidgetPath() << + "Path <" << GlobalConfig::GetUserPreloadedWidgetPath() << "> does not exist."); } return if_ok; @@ -321,7 +323,10 @@ extern "C" WrtInstallerStatusCallback status_cb, WrtProgressCallback progress_cb, wrt_widget_update_mode_t update_mode, - bool quiet) + bool quiet, + bool preload, + std::shared_ptr pkgmgrInterface + ) { UNHANDLED_EXCEPTION_HANDLER_BEGIN { @@ -336,7 +341,9 @@ extern "C" new InstallerCallbacksTranslate::StatusCallbackStruct( userdata, status_cb, progress_cb), translateWidgetUpdateMode(update_mode), - quiet))); + quiet, + preload, + pkgmgrInterface))); } UNHANDLED_EXCEPTION_HANDLER_END } @@ -344,7 +351,8 @@ extern "C" EXPORT_API void wrt_uninstall_widget(const char * const pkg_name, void* userdata, WrtInstallerStatusCallback status_cb, - WrtProgressCallback progress_cb) + WrtProgressCallback progress_cb, + std::shared_ptr pkgmgrSignalInterface) { UNHANDLED_EXCEPTION_HANDLER_BEGIN { @@ -352,14 +360,18 @@ extern "C" LogInfo("[WRT-API] UNINSTALL WIDGET: " << widgetPkgName); // Post uninstallation event CONTROLLER_POST_EVENT( - Logic::InstallerController, - InstallerControllerEvents::UninstallWidgetEvent( - widgetPkgName, - WidgetUninstallationStruct( - InstallerCallbacksTranslate::uninstallFinishedCallback, - InstallerCallbacksTranslate::installProgressCallback, - new InstallerCallbacksTranslate::StatusCallbackStruct( - userdata, status_cb, progress_cb)))); + Logic::InstallerController, + InstallerControllerEvents::UninstallWidgetEvent( + widgetPkgName, + WidgetUninstallationStruct( + InstallerCallbacksTranslate::uninstallFinishedCallback, + InstallerCallbacksTranslate::installProgressCallback, + new InstallerCallbacksTranslate::StatusCallbackStruct( + userdata, status_cb, progress_cb), + pkgmgrSignalInterface + ) + ) + ); } UNHANDLED_EXCEPTION_HANDLER_END } diff --git a/src/wrt-installer/wrt_installer_api.h b/src/wrt-installer/wrt_installer_api.h index cd83c5b..6f2bea6 100755 --- a/src/wrt-installer/wrt_installer_api.h +++ b/src/wrt-installer/wrt_installer_api.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -151,7 +153,10 @@ typedef enum wrt_widget_install_mode_e /* Force install policy */ - WRT_WIM_POLICY_FORCE_INSTALL = WRT_WIM_POLICY_ALWAYS_INSTALL + WRT_WIM_POLICY_FORCE_INSTALL = WRT_WIM_POLICY_ALWAYS_INSTALL, + /* Installation from directory - forced update + */ + WRT_WIM_POLICY_DIRECTORY_FORCE_INSTALL } wrt_widget_update_mode_t; int wrt_installer_init(void *userdata, @@ -196,7 +201,9 @@ void wrt_installer_shutdown(void); * void *user_parameter, * WrtInstallerStatusCallback status_callback, * WrtProgressCallback progress_callback, - * wrt_widget_update_mode_t update_mode); + * wrt_widget_update_mode_t update_mode, + * bool quiet, + * bool preload); * * @brief Installs widget from given path * @@ -213,6 +220,8 @@ void wrt_installer_shutdown(void); * If you don't want to get progress data, this * should be NULL * @param [in] install_mode Installation mode + * @param [in] quiet quiet mode + * @param [in] preload preload widget install * @return Nothing (status returned in callback). * * Sample code: @@ -221,7 +230,9 @@ void wrt_installer_shutdown(void); * NULL, * install_cb, * progress_cb, - * WRT_WIM_POLICY_WAC); + * WRT_WIM_POLICY_WAC, + * false, + * false); * @endcode * * @see wrt_installer_uninstall_widget @@ -231,7 +242,10 @@ void wrt_install_widget(const char *path, WrtInstallerStatusCallback status_callback, WrtProgressCallback progress_callback, wrt_widget_update_mode_t update_mode, - bool quiet); + bool quiet, + bool preload, + std::shared_ptr pkgmgrInterface + ); /** * @fn void wrt_installer_uninstall_widget (const char * const pkg_name, @@ -264,7 +278,8 @@ void wrt_install_widget(const char *path, void wrt_uninstall_widget (const char * const pkg_name, void* userdata, WrtInstallerStatusCallback status_cb, - WrtProgressCallback progress_cb); + WrtProgressCallback progress_cb, + std::shared_ptr pkgmgrSignalInterface); /** * @fn void wrt_install_plugin(const char *pluginDirectory, -- 2.7.4