From 120f815cc01304b21441e7682b5996218379f70e Mon Sep 17 00:00:00 2001 From: Jihoon Chung Date: Sat, 22 Jun 2013 21:17:07 +0900 Subject: [PATCH] [Release] wrt-installer_0.1.85 Change-Id: I543a7fb595d9a3eea4c064bf427ebae65d27ad97 --- configuration/config.xml | 19 +- configuration/validate-config.xml.sh | 2 + configuration/widgets.tizen.xsd | 22 +- etc/CMakeLists.txt | 2 + etc/default_icon_tizen.png | Bin 0 -> 12193 bytes packaging/wrt-installer.spec | 3 +- packaging/wrt-preinstall-widgets.service | 4 +- src/configuration_parser/widget_parser.cpp | 65 ++++-- src/jobs/plugin_install/job_plugin_install.cpp | 2 +- src/jobs/plugin_install/job_plugin_install.h | 5 +- src/jobs/plugin_install/plugin_install_task.cpp | 47 ++--- src/jobs/plugin_install/plugin_installer_context.h | 3 +- src/jobs/plugin_install/plugin_metafile_reader.h | 5 +- src/jobs/widget_install/directory_api.cpp | 2 + src/jobs/widget_install/job_widget_install.cpp | 60 ++---- src/jobs/widget_install/manifest.cpp | 22 +- src/jobs/widget_install/manifest.h | 13 +- src/jobs/widget_install/task_certify.cpp | 38 ++-- src/jobs/widget_install/task_certify.h | 3 + src/jobs/widget_install/task_file_manipulation.cpp | 46 ++--- src/jobs/widget_install/task_install_ospsvc.cpp | 9 +- src/jobs/widget_install/task_manifest_file.cpp | 51 ++--- src/jobs/widget_install/task_remove_backup.cpp | 3 +- src/jobs/widget_install/task_widget_config.cpp | 8 +- src/jobs/widget_install/widget_unzip.cpp | 109 ++++++---- src/jobs/widget_uninstall/job_widget_uninstall.cpp | 27 +-- src/jobs/widget_uninstall/task_remove_files.cpp | 88 ++++---- src/jobs/widget_uninstall/uninstaller_context.h | 3 +- src/logic/installer_logic.cpp | 59 ++++-- src/logic/installer_logic.h | 5 +- src/misc/widget_location.cpp | 16 +- src/misc/widget_location.h | 10 +- tests/general/CMakeLists.txt | 14 +- tests/general/WidgetUpdateTests.cpp | 223 +++++++++++++++++++++ tests/general/widgets/widgetUpdateVer100Signed.wgt | Bin 0 -> 23379 bytes .../general/widgets/widgetUpdateVer100Unsigned.wgt | Bin 0 -> 19629 bytes tests/general/widgets/widgetUpdateVer220Signed.wgt | Bin 0 -> 23398 bytes .../widgetUpdateVer220SignedAnotherAuthor.wgt | Bin 0 -> 23430 bytes .../general/widgets/widgetUpdateVer220Unsigned.wgt | Bin 0 -> 19647 bytes .../widgetUpdateVer220UnsignedDifferentId.wgt | Bin 0 -> 19649 bytes 40 files changed, 657 insertions(+), 331 deletions(-) create mode 100755 configuration/validate-config.xml.sh mode change 100755 => 100644 configuration/widgets.tizen.xsd create mode 100644 etc/default_icon_tizen.png mode change 100755 => 100644 src/configuration_parser/widget_parser.cpp mode change 100755 => 100644 src/jobs/widget_install/manifest.cpp mode change 100755 => 100644 src/jobs/widget_install/manifest.h mode change 100755 => 100644 src/jobs/widget_uninstall/task_remove_files.cpp create mode 100644 tests/general/WidgetUpdateTests.cpp create mode 100644 tests/general/widgets/widgetUpdateVer100Signed.wgt create mode 100644 tests/general/widgets/widgetUpdateVer100Unsigned.wgt create mode 100644 tests/general/widgets/widgetUpdateVer220Signed.wgt create mode 100644 tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt create mode 100644 tests/general/widgets/widgetUpdateVer220Unsigned.wgt create mode 100644 tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt diff --git a/configuration/config.xml b/configuration/config.xml index 038ec52..f33ce7e 100644 --- a/configuration/config.xml +++ b/configuration/config.xml @@ -7,7 +7,7 @@ - + @@ -26,4 +26,21 @@ + + + + WEB DYNAMICBOX + WEB DYNAMICBOX + WEB DYNAMICBOX + + + 1x1 + 2x1 + 2x2 + + + + + + diff --git a/configuration/validate-config.xml.sh b/configuration/validate-config.xml.sh new file mode 100755 index 0000000..a242910 --- /dev/null +++ b/configuration/validate-config.xml.sh @@ -0,0 +1,2 @@ +#!/bin/sh +xmllint --schema widgets.xsd config.xml diff --git a/configuration/widgets.tizen.xsd b/configuration/widgets.tizen.xsd old mode 100755 new mode 100644 index 238d216..1b7c8c6 --- a/configuration/widgets.tizen.xsd +++ b/configuration/widgets.tizen.xsd @@ -77,6 +77,7 @@ + @@ -135,11 +136,11 @@ - - - - - + + + + + @@ -150,7 +151,7 @@ - + @@ -184,6 +185,7 @@ + @@ -228,7 +230,13 @@ - + + + + + + + diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt index c48caa4..372dcbe 100644 --- a/etc/CMakeLists.txt +++ b/etc/CMakeLists.txt @@ -1,3 +1,5 @@ SET(ETC_DIR ${PROJECT_SOURCE_DIR}/etc) INSTALL(PROGRAMS ${ETC_DIR}/wrt_preinstall_widgets.sh DESTINATION /usr/bin/) +INSTALL(FILES ${ETC_DIR}/default_icon_tizen.png DESTINATION share/wrt-engine/) + diff --git a/etc/default_icon_tizen.png b/etc/default_icon_tizen.png new file mode 100644 index 0000000000000000000000000000000000000000..1c3ecd61cbf721d166cc48c576ce7af2fdfedb3f GIT binary patch literal 12193 zcmV;SFJ91zP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z001P+NklWs_LHU>Dk?xUGJ`UkQ7bQ;(dyPXD<6bFBD~S^T^n2y%GcA3lBp}-vi_v#{*^wW>KP@b<8}XJ%*>uQj&g7dR0*~XEIF3=CM;t|HrO;Z> z7sM>cnF}9BK+aKCKSx>CS}b!s;JA=8Pf^Du+F2f8tR?D2Bv}5a74TY9@Ke<`Nfe_B z>S${}4q46&CnwLDMYM}3Nxx@AyGU$5$LftSbh}-o*8KXW$5#&|PZcb26oIwmZT?$` zXct$K{{Mk!qbMRy6296D_~NeMT34V1Bqlx2m^qO1%_Q16$BjeKw<6IRW9aoFkb>Xd z_4!}71X>ET0Hnp(DVgs#k!Tkd{^0r41HKiBHc1kCy&mVfKEHQI@YQ{RmVmJ!1sI5J zDu}y+oVz62g~|@{xc6W9(f+&f=lyy%X&`CF!Gyc8-8& zz{%YZZIUE(dp*A1Q2h6sl9%@TR-X#qj=~SpW<0=7PkfFk$h)@YyE)Ffn_d`l9$-cr zM={+v;y1TEK6x1qVv8QJc8frazz+rzYZro%#gn83J>{N-KRjMP7@}RggpkBBonDt0 zb~OL^oJGk=vPHV%_}s1GRgHz%Oj`Rm z5ewrUj>pwU3G%%q+S$kVJyzehZq+eM$8j8!7{jM;PhQhlS7s37N?=qWgHl8$uKrde z+Ih$8BO{&%)UE1uyC|jj+V1oqAhAQJ86;q1&=lL@``8Ccw8w;|nYEv>dpo5RaleUn zR>P#*>rpC~XDVQ*giJJ)60tCjq)jINzh?oxhgRP=7Ry*3aICSA1&MYVSD3_*7(*wD z5mve5W()<4C}H3g&Jz;5NaKBRYkseUKiLnkc7B`h7)7)rrx>gyPGYbSdYV<$<5uhq zKhzXOI8MlNKsFP0(a~{<)+7dFjq{=;!6LBMIJ7VZq;%0(`n*7(l|%@6SArjrPX?B> zo!8u66xSDkoa}MkP6zF2D&;cIh1YrEP-89WXpF@oQmGEVQ<8q*KKuyNR|=RUAxdIQ zoL~i5V=*?((xgZU+#-~6?_r&uwe}DKtQGj4X7{kg%XfOb(+&9Ifsd6ED+EvG4Ijuy zeE(9HBGVjq?NH2;gmCKY$C4TaW0-t}$I6)wAX&4jUU~!RAAAWod z@5>pYUXMy;3D5Jeo=4z$Alx;y)~;79oN~h;L@5afgcRvJL9^N9SHF6RfAOYZ&&v@7 zK1OS-6j&j6u>lb9Z@oN!?L>#4SZ)$^dw5zQq?}*z%rcbC$Yl@(jTf>W@K}g324f5= zwZLk6k)Q3!Bifz?&XA#Z5C!`K*@yF&w`xM*AnBxKCM(5 z&M}~#0{kO@qg5V3?E$!`THL(^Y32V<*5?^f9ZXS4{?n*-@L_%l@(T& zSIFf;q*NnrY^-bIJB)W?>t8>6-+%3=fB6k|j3CZ=&iXULAODtF>{pq`qly3};s3Tu zT#ZBiWO&H4y&V^>YBd#-r}qOM@cd=3+eK?lKA#)AoOQ9gG5qXzEFrrse)xTo3m49@ z7ss4=XnF{}C?4Pa( z=Lu56&BW(3?K;g+@iDfEyFENl52L!VZ?1U&L_4cN-mm}UbNPwaj2VWgfBC79mtT63 za;e0LwbPVJMU>JEL_X0pakd1BFo%tK=ZwXG-ML zhZ#A+1EYjIq6h(BjH)!yd|2&M={E2^?Q(|EQri>`xDP}-QERc5B(47_rIAvOz?iW% zEep6?=zBc=#1pKpo}yeS4~1_h8%2HPIjoOKl7z%0#7X)%iD|Z4Y;0`s%F8cP*m{$H z_9p~C_E?{E-pyAx1qUbI$9g#EYhiF>c@>6WI(qVzcII;y503oUj(9 z6iTYQ9{G-w7=a)R{jpHd4oK7*2Sr**mX?-i93Eng!74Gcwdf`j&46F};E{cc{r!Ee zT)x7|6DKgn^5*NW@mJ2AWu>sfr#3vcjYzYz;YkCSk(1Uwi;(;Of7)wtR(5zoHV}!KDA!O5q0qolcirE*uJHVz|k=T2K^?2)_S$4i6h#x_A)*oLXB$AlTjA;o8+J zJXhZ3pFjR2pWX`i!hSdgJ+twC+VjtPEk58id0MsD-`wC}e~$|X2Lzta%83;`tw%g~ zkcdsoXsxvz?Co=A#p6;Z$2SfwpGqXp79<}kS)MN${HTKv!hMK-k!#LaNFVvnr=ZEvx+yT|F%YvjUQT7)}65Cq)b z+{C;5b^giYPw+&(#(%n19Ep4emM*80@N+?%=Ykd=@LC*huCu+p!|R6!_(4FiSmdG8 zr^)B@|7rEoL68{?EeQd>=h1Gr(MlmFyv`1kI0`|j7k4|n zd+{PCPM)MtC?ci6T8rmtma0`e&u4pko43xr$qzpKFvYbq{Q6FwjYv-ttAwJmd}qGJ z(|(ud!ZwGu*V(?Y!y5+&1Ytm_SfpM*OBjauzK`#DX*qIomOT2AW7O?*j-kP?Bze}o_mgG>U}7kUak z#tz`e4sK4+K@iYtcgW|$(RzHp!DCDcL79-Z7jf~z13<65U67{oZ z$mMc)zK`$uF36ZtcF0ynC-Z6JqF?tK33@P5#I@Y=jJxw zXf`RNWt95av*f}YzVG4reW7Ow*3M191`V0f&ooqm)|yhO#P;?!A1vnh%DzGgo4TY; zS>L8aWSwV7xX=>(;=77}c@ds2N`CmH;rWWkBRR|EOP6Ri8x#u#O2q<7>lF8gL`=p5 z$Uuy>V6a3{g!a6VFf@r1k_?RYdJ*e4ZgBeaLxf=ng0bne(R-y7<#HMAd2DZQvwdfa zAI~+|y0pbNnhlDDBIQzvwbfJjVSukawC6cU8x!cj%E!ykjDCh;6f~okDupBrLpC=z zd1f`?s|RWzWN9;`#PqPtU^#y%c^-_2&oh@14W5RNaEOqk6Lr_oeL~4uTUx#=Qm8~Cx8jDF=)@@ zkuzs0m5byG1>Qb)o_4cEp^(S-1GH8H2%HpX*4pPZW5#$uXOpP$Tp;ir3_Ynk6qU!G z5hGqOanDd8$(Xynv@7@-iecRI&GS*76%6hyz}-2dc7{Ca)tVGoz>M?pUj z29p@t?KYlvOH(W5G8-GWxO(|r!hD`w5O8X34bS(-CeaK@V$y&>;`<)uQjt=jKrR=$ zL{mu@i3#T!%PTduceY95*oBdc)cKjNq-h@FNO%rmNGZwXa%^sH@@=azUu&qT)-R<+ znhX~RNcxGTac{QXhIhLjYoxx^h~mUG=n;5Ykq-(4 zfsf~TX%|fr$H{07A}tHm>s7)aq|@z?*M&I(UBK$6o@4uo*z_V77KhKkV}3HUb_vQ% zCMP2qB#sA+b?psdEuXsyKeHx?;}}nSC@IP1bL4U%rDBO{b%{>5ORL%Bu+iYw#s*j3 zy-cZGqE=tV_cZJ4>pc9>Lr5vHX^AAC&lBcyLoc?5POpcQ0wE=ykf^jY+^<9R^9DQ8 z0~zK)LI{+UoH)76l`GdUi5U$q7b03_dPrXh+8$9(P)d`_f~vFf8b8v<#P9idEahn0!B+ zp9+0p5EAy4v9v_57a^p;_x#Z*gfXm*qL^;CgVq|8Bv|Q$*(Y-;<)GwYl||Y#epe8? z;rNl7k|X94J6k*WzCY2AIFc8pDPhpZ06DF6Y{#MoKk%_h!ZW%_LD`Yg>jeBT`dFp# zBdkRj%kNyb2q9eNYKOaqWJeyexquL2;1z|u%UlP2)hWlvaZI<{bzQQwSKPnFN$hTM zOdQ2-0eBn_o==j5ICjrRk!x!viD9{3Pa8VPFgYB{Xh##Uv1rFmmLU3HS5EEil8wh* zJtki$u(PwncNXH2e(10|CCWUCTVWk~g znq(&+XIx=3GU3s(gj9+`p}>tBH~47%Bws%Ch%+QSAZ5u&G-QNzK~Ne>3S+s|Ot{k2 zoTNuCZ$_)A>6<2rA&w)A1?_2ad6)9Xal-!o0mekG%{K*Sl~R;TC2ntSa^>wKd6D8IFrnP_NZ!G@9(~?Q-MB4WyFPmzP;tSs@HUR}9P~dRaw` zj-?2yOBJqbO}E=~<&6c1mN^_@7s&&%XDj8Bo@>{y^GxXuo5fYWa^O$zjiynMVmJry zA|Zn`hSzQ<=%+l|?G83D1EB}G9KPqJLKhQ*(ypx;(>QFTrCyIDiHQ^AW<8}Ojv_pz zDHQUAVMw`Lrqij>>vd^1TO2kHdGqx*2Fh4oSs@qZNKDVQH4}sJGag|rQVN1Fq*5xg zyR(y)PQ*e)I~f^eykwC)V9-<%kk1!buGhJK?HWJ$WJr}FpV`ZeAN?e+))Ka(U0w5L%iyp>92dettSc87z*19qE+pa0+cEEgpoc_iTD@6Yqt zN-zRLrDBO74Cr-xsJvPLa;8{)RtbY*+%aa{J>O$xc^N4sH?Cbn${YNxr=RAkiul^T z#CV$6HzbMWVXwy-KjLIy2SPGNO$^J9*8j7kCByRa?#?b7H*d0bYR#1zq#!Y7Fznm6 zs6ru694~Qa^A1rIqm`O~1cAWw+~~UJc}T7K?YBDsY&8rooNM#Kxi#d2;v)wd&_SH6@KfliRf7>p9{ku<6EEdtePp{X*4}zIQJF+Bq zj2k8=aE%b5SDZ@-mG56E| zaYYE>M#wK+yojegmX<0mt{)R7nTfdmb;_j@`}+rjhJJt9N48{atRaee940Q(;s_taP|7TMn3#`C?DjOP>W_##4Uvx!(H@fzu0+G+jF(aci{ zK^TUtEHCrOBacvBTH>7xZ_{ixIdkSLQYjjZ22m6Z5}-c0^^+Wz_>8{RpOR>`TC8tu z&}=kVURfpxLnp|7_H2hkPFdl*>^Wq4c^M%jaTHH{C!2=87I^8FrCln}DHUm#inJ;v zI;CQ|X22~~0=T|w_=V4Hv(<=^QV=J})YzV}{z?|2?1-{#W;pkV66-vEkWx`B7Vrb# zdBdGMy!PrVoIU%fYp6GyBuRpwR#uN%jVVOGue-y|8`oJ`S)ouUjC8@6SQ{+H?k!7| z3UL&%d3!URbWZ+=wPvo-{|AkbC=A?esB|NWRxrf&ene(8QRvet|>y2IZ79%s%zib-PH?Y5hCn^+TUX|`Hy z-MPcssWms2I7Xn;R-BL4Z$_1o3qzKcDr{|S(TgHH?YaK4=kdF{WfHA24xu&suN|`lvNFshVl#>MKCA{8DM>G{c;xaqcD8r8bm485 zsx=;Z_#qAt59xNh18=Z^7J_S6u2QenC>4w8x?VfC5#rYKnK3xBBez1KKorMpZ*3!m zAnNrv%vHG*hX^G`Aq5m zVxdTw@rKu4d6lz|J&Nb~^r8rD4BGR#cJ&(hTu7y|gwkr}bw{hZu5O=&sqrG4F$S$P z`9hxN!6At?{9!APr{rYeW4a>@A4{MR(m+#8`w3d>xrx}+;KR;L#P0uYA+9dtQ%lRj zd%L^bxON>W1&==dIMxbwcXsHs+nhdq8sGCKNBU+MfmH#A?;rDo}79l`;9+gUkFmQc_%2Jh|f1$yjBwv#6&IVJ=`Owe_R~9 zT~7YbEuY`LVNkw@jRiI_SlmKwafA|*B%#~wjx5yf<9+{LN=czm;L^oQXstMPY7MOw zo12?Fw0n^sDf|3JXXOYbj7CZy@(yY4xdAcK+SMYEGhPcCDM#PauSFblw~)jbI-L&R zXyo}X7X>B|Smg$ARTQVI7KKy7oF5rVl7x1F( z=DPtMZIMDEl|-rpn<|0Gl>}rG&*TNS-*h~I`%x5;%jH2x-hBOaR#sN1)obavy32C& z`8@TdDjPR%^6|&(Ts8&nSbwS#vV2ezJ?haO`%1ZOa>ilC&anFIe+G%zdk8uG=X<>f zE8u_LF7U_A01>!ev5XT`9AjdY?ph*IGD5`yE2cwIf5Y#-#rM6SSS-=$cGy_I$?B<7 zRI5uaV->^20$M4`l?t6shv?ede9!3|pNZG9vCdRacvc>8u)9YXhM9#KV;nHG7Bs4f zv=qVEJ`sxx^wJ{@Yd&>krqENu@AaIS5KClSU~_9HYBEtQ4qt6p~IA z4ZU;)P8`Q6-WNGI*r(NOvAViSrBZRD>UOjyY_WJ+Q?1olzj>1<_uk=$s*2Ait8;UJ zkBA*Q?GB}a%hZn|+VT8gtQ2uX4saiL7_`=nmanT4zqVgN`))6?BoUZIVvLJ|60K2Q zjEZ86j!B}}DW)4?MTCmoMjikqFQ(J!5XUjOT#n_H6|TH{8GyC5QxuCu*Tk7(41MW_ zLBR6L3L6{id{?E+rV4q}E=^U!lIXG2*=1MjiGt!>$eB@o*IAo=&^yX@yFHYr`NBbo zmQZMI)A>aSu^};*#7Km(m{bwcOVCk-iIiK?S{rwJ0OI511DsP`V zPoY#~WqFx=zlUJwcdLXH6bgB2wHlY-z07w!vBXVLqKTf!1D>|~9PA&E%jE{0zJ(!Y zOj&k(o$v$%-KF5CK~oeveEvdjg|Bo<1S%cqGS+R(DwNxdHF1mgumYnbQY(z7kgLu3fvz>Zw(#)hb>(#eCFQ$hg(| zzE7=IWqo~}#~W8TEO~rgog65jYi+$c!l@;}wxj_Y@WIBjr7Qx_F!O=g(6r7Fb?c zC7;Wuz2#$!h0N(zDW#~CD|9+tf{hD2|4_&q{wkH;K9SZAeikI!S&A5GN!q(8NzeNw z3b%bgLZ{nhE2#11co|=%I6tuNG3Xh2+@J9oD(5lX=EuuBJQLsI{Q1k&s#R+Bdb$CJ zxGTt+JZ?DT6@&rRYL#0X8$6o3z=@>>`v(UELFfhq79m>Z3m;|`04nC}tzf z@lmx$Vl76xEr?C}^CO9MzlN7s(tRQrKA-+b&of?&Roz22cG+7(-j_>=NJaKYF;YUHtEWr=+fN90Ed0Xx-xIWe- zhDPI%lY6hE%aM+;hBdGaKMd;zUBVq%TiF~>sYbgL{DrQH?= zQYoTdG}r}&1$Uf3O8B{=GZ!(>P=*wO+ENui@Ckx| zFqccMUJQqu?t*AJM(J2vDiU7^0omt-4=CJMT|V{> if previous item was not in tizen namespace } + m_data.startFileEncountered = true; m_data.startFileNamespace = m_namespace; //we're consciously setting startFile even if m_src is null or invalid. @@ -1373,24 +1374,33 @@ class SplashParser : public ElementParser virtual void Accept(const XmlAttribute& attribute) { - if (attribute.name == L"src") { - if (attribute.value.size() > 0) { - m_src = attribute.value; + if (m_properNamespace) + { + if (attribute.name == L"src") { + if (attribute.value.size() > 0) { + m_src = attribute.value; + } } } } - virtual void Accept(const Element& /*element*/) - {} + virtual void Accept(const Element& element) + { + if (element.ns == + ConfigurationNamespace::TizenWebAppNamespaceName) + { + m_properNamespace = true; + } + } virtual void Accept(const Text& /*text*/) {} virtual void Verify() { - if (m_src.IsNull()) { - LogWarning( - "src attribute of splash element is mandatory - ignoring"); + if (m_src.IsNull()) + { + LogWarning("src attribute of splash element is mandatory - ignoring"); return; } @@ -1399,12 +1409,14 @@ class SplashParser : public ElementParser SplashParser(ConfigParserData& data) : ElementParser(), - m_data(data) + m_data(data), + m_properNamespace(false) {} private: DPL::OptionalString m_src; ConfigParserData& m_data; + bool m_properNamespace; }; class BackgroundParser : public ElementParser @@ -1616,14 +1628,18 @@ class AppWidgetParser : public ElementParser virtual void Verify() { + std::pair boxLabel; if (m_label.empty()) { - ThrowMsg(Exception::ParseError, - "box-label element cannot be empty - ignoring"); + LogWarning("box-label element is empty"); + boxLabel.first = DPL::FromUTF8String(""); + boxLabel.second = DPL::FromUTF8String(""); + m_data.m_label.push_back(boxLabel); + } + else { + boxLabel.first = m_lang; + boxLabel.second = m_label; + m_data.m_label.push_back(boxLabel); } - std::pair boxLabel; - boxLabel.first = m_lang; - boxLabel.second = m_label; - m_data.m_label.push_back(boxLabel); } BoxLabelParser(ConfigParserData::LiveboxInfo& data) : @@ -1705,6 +1721,9 @@ class AppWidgetParser : public ElementParser if (attribute.name == L"preview") { m_preview = attribute.value; } + if (attribute.name == L"use-decoration") { + m_useDecoration = attribute.value; + } } } @@ -1731,10 +1750,11 @@ class AppWidgetParser : public ElementParser "size is mandatory - ignoring"); } - std::pair boxSize; - boxSize.first = m_size; - boxSize.second = m_preview; - m_data.m_boxSize.push_back(boxSize); + ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo; + boxSizeInfo.m_size = m_size; + boxSizeInfo.m_preview = m_preview; + boxSizeInfo.m_useDecoration = m_useDecoration; + m_data.m_boxSize.push_back(boxSizeInfo); } explicit BoxSizeParser( @@ -1747,6 +1767,7 @@ class AppWidgetParser : public ElementParser private: DPL::String m_size; DPL::String m_preview; + DPL::String m_useDecoration; bool m_properNamespace; ConfigParserData::LiveboxInfo::BoxContentInfo& m_data; }; @@ -2615,9 +2636,9 @@ class MetadataParser : public ElementParser } NormalizeString(m_key); NormalizeString(m_value); - ConfigParserData::Metadata metaData(*m_key, *m_value); + ConfigParserData::Metadata metaData(m_key, m_value); FOREACH(it, m_data.metadataList) { - if (!DPL::StringCompare(it->key, *m_key)) { + if (!DPL::StringCompare(*it->key, *m_key)) { LogError("Key isn't unique"); return; } diff --git a/src/jobs/plugin_install/job_plugin_install.cpp b/src/jobs/plugin_install/job_plugin_install.cpp index 38c0aef..811c049 100644 --- a/src/jobs/plugin_install/job_plugin_install.cpp +++ b/src/jobs/plugin_install/job_plugin_install.cpp @@ -28,7 +28,7 @@ namespace Jobs { namespace PluginInstall { -JobPluginInstall::JobPluginInstall(std::string const &pluginPath, +JobPluginInstall::JobPluginInstall(DPL::Utils::Path const &pluginPath, const PluginInstallerStruct &installerStruct) : Job(PluginInstallation), diff --git a/src/jobs/plugin_install/job_plugin_install.h b/src/jobs/plugin_install/job_plugin_install.h index 0af9c04..c4a59ee 100644 --- a/src/jobs/plugin_install/job_plugin_install.h +++ b/src/jobs/plugin_install/job_plugin_install.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace Jobs { namespace PluginInstall { @@ -47,7 +48,7 @@ class JobPluginInstall : /** * @brief Automaticaly sets installation process */ - JobPluginInstall(std::string const &pluginPath, + JobPluginInstall(DPL::Utils::Path const &pluginPath, const PluginInstallerStruct &installerStruct); WrtDB::DbPluginHandle getNewPluginHandle() const @@ -56,7 +57,7 @@ class JobPluginInstall : } std::string getFilePath() const { - return m_context.pluginFilePath; + return m_context.pluginFilePath.Fullpath(); } bool isReadyToInstall() const { diff --git a/src/jobs/plugin_install/plugin_install_task.cpp b/src/jobs/plugin_install/plugin_install_task.cpp index 65333ba..861dbc2 100644 --- a/src/jobs/plugin_install/plugin_install_task.cpp +++ b/src/jobs/plugin_install/plugin_install_task.cpp @@ -87,16 +87,9 @@ void PluginInstallTask::stepCheckPluginPath() { LogInfo("Plugin installation: step CheckPluginPath"); - struct stat tmp; - - if (-1 == stat(m_context->pluginFilePath.c_str(), &tmp)) { + if(!m_context->pluginFilePath.Exists()){ ThrowMsg(Exceptions::PluginPathFailed, - "Stat function failed"); - } - - if (!S_ISDIR(tmp.st_mode)) { - ThrowMsg(Exceptions::PluginPathFailed, - "Invalid Directory"); + "No such path"); } SET_PLUGIN_INSTALL_PROGRESS(PLUGIN_PATH, "Path to plugin verified"); @@ -106,17 +99,15 @@ void PluginInstallTask::stepParseConfigFile() { LogInfo("Plugin installation: step parse config file"); - struct stat tmp; - - std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR + - std::string(GlobalConfig::GetPluginMetafileName()); + DPL::Utils::Path filename = m_context->pluginFilePath; + filename /= GlobalConfig::GetPluginMetafileName(); - if (-1 == stat(filename.c_str(), &tmp)) { + if(!filename.Exists()){ m_dataFromConfigXML = false; return; } - LogInfo("Plugin Config file::" << filename); + LogInfo("Plugin Config file::" << filename.Filename()); Try { @@ -136,7 +127,7 @@ void PluginInstallTask::stepParseConfigFile() } Catch(ValidationCore::ParserSchemaException::Base) { - LogError("Error during file processing " << filename); + LogError("Error during file processing " << filename.Filename()); ThrowMsg(Exceptions::PluginMetafileFailed, "Metafile error"); } @@ -148,8 +139,8 @@ void PluginInstallTask::stepFindPluginLibrary() return; } LogDebug("Plugin installation: step find plugin library"); - std::string pluginPath = m_context->pluginFilePath; - size_t indexpos = pluginPath.find_last_of('/'); + DPL::Utils::Path pluginPath = m_context->pluginFilePath; + size_t indexpos = pluginPath.Fullpath().find_last_of('/'); if (std::string::npos == indexpos) { indexpos = 0; @@ -157,7 +148,7 @@ void PluginInstallTask::stepFindPluginLibrary() indexpos += 1; // move after '/' } - std::string libName = pluginPath.substr(indexpos); + std::string libName = pluginPath.Fullpath().substr(indexpos); libName = GlobalConfig::GetPluginPrefix() + libName + GlobalConfig::GetPluginSuffix(); LogDebug("Plugin .so: " << libName); @@ -180,16 +171,16 @@ void PluginInstallTask::stepLoadPluginLibrary() DISABLE_IF_PLUGIN_WITHOUT_LIB() - std::string filename = m_context->pluginFilePath + DIRECTORY_SEPARATOR + - m_pluginInfo.m_libraryName; + DPL::Utils::Path filename = m_context->pluginFilePath; + filename /= m_pluginInfo.m_libraryName; - LogDebug("Loading plugin: " << filename); + LogDebug("Loading plugin: " << filename.Filename()); - void *dlHandle = dlopen(filename.c_str(), RTLD_LAZY); + void *dlHandle = dlopen(filename.Fullpath().c_str(), RTLD_LAZY); if (dlHandle == NULL) { const char* error = (const char*)dlerror(); LogError( - "Failed to load plugin: " << filename << + "Failed to load plugin: " << filename.Filename() << ". Reason: " << (error != NULL ? error : "unknown")); ThrowMsg(Exceptions::PluginLibraryError, "Library error"); } @@ -211,7 +202,7 @@ void PluginInstallTask::stepLoadPluginLibrary() if (rawEntityList == NULL) { dlclose(dlHandle); - LogError("Failed to read class name" << filename); + LogError("Failed to read class name" << filename.Filename()); ThrowMsg(Exceptions::PluginLibraryError, "Library error"); } @@ -222,7 +213,7 @@ void PluginInstallTask::stepLoadPluginLibrary() if (NULL == onWidgetInitProc) { dlclose(dlHandle); - LogError("Failed to read onWidgetInit symbol" << filename); + LogError("Failed to read onWidgetInit symbol" << filename.Filename()); ThrowMsg(Exceptions::PluginLibraryError, "Library error"); } @@ -274,7 +265,7 @@ void PluginInstallTask::stepLoadPluginLibrary() const js_entity_definition_t *rawEntityListIterator = rawEntityList; LogInfo("#####"); - LogInfo("##### Plugin: " << filename << " supports new plugin API"); + LogInfo("##### Plugin: " << filename.Filename() << " supports new plugin API"); LogInfo("#####"); while (rawEntityListIterator->parent_name != NULL && @@ -308,7 +299,7 @@ void PluginInstallTask::stepRegisterPlugin() LogInfo("Plugin installation: step register Plugin"); m_pluginHandle = - PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath); + PluginDAO::registerPlugin(m_pluginInfo, m_context->pluginFilePath.Fullpath()); SET_PLUGIN_INSTALL_PROGRESS(REGISTER_PLUGIN, "Plugin registered"); } diff --git a/src/jobs/plugin_install/plugin_installer_context.h b/src/jobs/plugin_install/plugin_installer_context.h index 026074a..fbf2db5 100644 --- a/src/jobs/plugin_install/plugin_installer_context.h +++ b/src/jobs/plugin_install/plugin_installer_context.h @@ -24,6 +24,7 @@ #include #include +#include //#include using namespace WrtDB; @@ -50,7 +51,7 @@ struct PluginInstallerContext PLUGIN_INSTALL_END }; - std::string pluginFilePath; ///< plugin directory + DPL::Utils::Path pluginFilePath; ///< plugin directory WrtDB::DbPluginHandle pluginHandle; // if this value is true the plugin model may be created // if not plugin installation has failed from some reason diff --git a/src/jobs/plugin_install/plugin_metafile_reader.h b/src/jobs/plugin_install/plugin_metafile_reader.h index b0c88f0..6a7734f 100644 --- a/src/jobs/plugin_install/plugin_metafile_reader.h +++ b/src/jobs/plugin_install/plugin_metafile_reader.h @@ -24,6 +24,7 @@ #define WRT_SRC_INSTALLER_CORE_PLUGIN_INSTALLER_TASKS_PLUGIN_METAFILE_READER_H_ #include +#include #include class PluginMetafileReader @@ -31,9 +32,9 @@ class PluginMetafileReader public: PluginMetafileReader(); - void initialize(const std::string &filename) + void initialize(const DPL::Utils::Path &filename) { - m_parserSchema.initialize(filename, + m_parserSchema.initialize(filename.Fullpath(), true, ValidationCore::SaxReader::VALIDATION_DTD, std::string()); diff --git a/src/jobs/widget_install/directory_api.cpp b/src/jobs/widget_install/directory_api.cpp index 678ec1d..a43b24c 100644 --- a/src/jobs/widget_install/directory_api.cpp +++ b/src/jobs/widget_install/directory_api.cpp @@ -71,6 +71,8 @@ bool DirectoryCopy(std::string source, std::string dest) outfile << infile.rdbuf(); outfile.close(); infile.close(); + + chown(destFile.c_str(), statInfo.st_uid, statInfo.st_gid); } } while (dEntryResult != NULL && return_code == 0); closedir(dir); diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index c10e6e8..9757223 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,7 @@ namespace // anonymous { const char * const CONFIG_XML = "config.xml"; const char * const WITH_OSP_XML = "res/wgt/config.xml"; +const char * const OSP_MANIFEST_XML = "info/manifest.xml"; //allowed: a-z, A-Z, 0-9 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$"; @@ -224,9 +226,8 @@ JobWidgetInstall::JobWidgetInstall( AddTask(new TaskEncryptResource(m_installerContext)); } - if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) - { + if (m_installerContext.mode.extension != + InstallMode::ExtensionType::DIR) { AddTask(new TaskUpdateFiles(m_installerContext)); AddTask(new TaskFileManipulation(m_installerContext)); } @@ -436,7 +437,8 @@ void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, widgetPath, tempPath, m_installerContext.widgetConfig.packagingType, m_installerContext.mode.rootPath == - InstallMode::RootPath::RO); + InstallMode::RootPath::RO, + m_installerContext.mode.extension); m_installerContext.locations->registerAppid( DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid)); @@ -627,7 +629,6 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( // Parse config ParserRunner parser; ConfigParserData configInfo; - Try { if (pkgType == PKG_TYPE_HOSTED_WEB_APP) { @@ -636,35 +637,24 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( new RootParser(configInfo, DPL::FromUTF32String( L"widget")))); - } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) { - std::string configPath; - configPath = tempPath; - configPath += "/"; - configPath += WITH_OSP_XML; + } else { + std::string configFile; + configFile = tempPath + "/" + CONFIG_XML; + if (!WrtUtilFileExists(configFile)) { + configFile = tempPath + "/" + WITH_OSP_XML; + } if (isReinstall) { // checking RDS data directory - if (access(configPath.c_str(), F_OK) != 0) { + if (access(configFile.c_str(), F_OK) != 0) { std::string tzAppId = widgetSource.substr(widgetSource.find_last_of("/")+1); WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId))); - configPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); - configPath += "/"; - configPath += WITH_OSP_XML; + configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); + configFile += "/"; + configFile += WITH_OSP_XML; } } - parser.Parse(configPath, - ElementParserPtr( - new RootParser( - configInfo, - DPL::FromUTF32String(L"widget")))); - } else { - std::string configFile; - if (pkgType == PKG_TYPE_HYBRID_WEB_APP) { - configFile = tempPath + "/" + WITH_OSP_XML; - } else { - configFile = tempPath + "/" + CONFIG_XML; - } parser.Parse(configFile, ElementParserPtr( @@ -684,6 +674,10 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( LogError("Failed to find installed widget - give proper tizenId"); return ConfigParserData(); } + Catch(Exceptions::WidgetConfigFileNotFound){ + LogError("Failed to find config.xml"); + return ConfigParserData(); + } return configInfo; } @@ -883,27 +877,17 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( const std::string &widgetSource, const std::string &tempPath) { - // Check installation type (direcotory/ or config.xml or widget.wgt) - if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) { - 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; } - std::string configFile = tempPath + "/" + CONFIG_XML; - if (WrtUtilFileExists(configFile)) { - return PKG_TYPE_NOMAL_WEB_APP; - } - - configFile = tempPath + "/" + WITH_OSP_XML; + std::string configFile = tempPath + "/" + OSP_MANIFEST_XML; if (WrtUtilFileExists(configFile)) { return PKG_TYPE_HYBRID_WEB_APP; } - return PKG_TYPE_UNKNOWN; + return PKG_TYPE_NOMAL_WEB_APP; } void JobWidgetInstall::setApplicationType( diff --git a/src/jobs/widget_install/manifest.cpp b/src/jobs/widget_install/manifest.cpp old mode 100755 new mode 100644 index 9688ee2..7a8bea6 --- a/src/jobs/widget_install/manifest.cpp +++ b/src/jobs/widget_install/manifest.cpp @@ -407,14 +407,20 @@ void LiveBox::serialize(xmlTextWriterPtr writer) writeAttribute(writer, "mouse_event", this->box.boxMouseEvent); writeAttribute(writer, "touch_effect", this->box.boxTouchEffect); - FOREACH(m, this->box.boxSize) + FOREACH(it, this->box.boxSize) { - std::pair boxSize = *m; startElement(writer, "size"); - if (!boxSize.second.empty()) { - writeAttribute(writer, "preview", boxSize.second); + if (!(*it).m_preview.empty()) { + writeAttribute(writer, "preview", (*it).m_preview); } - writeText(writer, boxSize.first); + if (!(*it).m_useDecoration.empty()) { + writeAttribute(writer, "need_frame", (*it).m_useDecoration); + } else { + // default value of use-decoration is "true" + writeAttribute(writer, "need_frame", DPL::String(L"true")); + } + + writeText(writer, (*it).m_size); endElement(writer); } @@ -498,8 +504,10 @@ void Privilege::serialize(xmlTextWriterPtr writer) void Metadata::serialize(xmlTextWriterPtr writer) { startElement(writer, "metadata"); - writeAttribute(writer, "key", this->key); - writeAttribute(writer, "value", this->value); + writeAttribute(writer, "key", *this->key); + if (!this->value.IsNull()) { + writeAttribute(writer, "value", *this->value); + } endElement(writer); } } //namespace Jobs diff --git a/src/jobs/widget_install/manifest.h b/src/jobs/widget_install/manifest.h old mode 100755 new mode 100644 index 30a849d..1729716 --- a/src/jobs/widget_install/manifest.h +++ b/src/jobs/widget_install/manifest.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace Jobs { namespace WidgetInstall { @@ -77,7 +78,7 @@ typedef DPL::String NcnameType, NmtokenType, AnySimpleType, LangType; typedef DPL::String OperationType, MimeType, UriType, TypeType, PackageType; typedef DPL::OptionalString InstallLocationType, CategoriesType; typedef DPL::String AppCategoryType; -typedef DPL::String KeyType, ValueType; +typedef DPL::OptionalString KeyType, ValueType; /** * xmllib2 wrappers @@ -405,15 +406,15 @@ typedef UiApplication UiApplicationType; /** * @brief LiveBox element */ -typedef std::list > boxSizeType; -typedef std::list > boxLabelType; +typedef WrtDB::ConfigParserData::LiveboxInfo::BoxSizeList BoxSizeType; +typedef WrtDB::ConfigParserData::LiveboxInfo::BoxLabelList BoxLabelType; struct BoxInfo { NcnameType boxSrc; NcnameType boxMouseEvent; NcnameType boxTouchEffect; - boxSizeType boxSize; + BoxSizeType boxSize; NcnameType pdSrc; NcnameType pdWidth; NcnameType pdHeight; @@ -436,7 +437,7 @@ class LiveBox { this->updatePeriod = x; } - void setLabel(const boxLabelType &x) + void setLabel(const BoxLabelType &x) { this->label = x; } @@ -457,7 +458,7 @@ class LiveBox NcnameType autoLaunch; NcnameType updatePeriod; NcnameType timeout; - boxLabelType label; + BoxLabelType label; NcnameType icon; NcnameType lang; BoxInfoType box; diff --git a/src/jobs/widget_install/task_certify.cpp b/src/jobs/widget_install/task_certify.cpp index 68189ac..6223426 100644 --- a/src/jobs/widget_install/task_certify.cpp +++ b/src/jobs/widget_install/task_certify.cpp @@ -23,6 +23,7 @@ //SYSTEM INCLUDES #include #include +#include #include #include //TODO is it necessary here? #include @@ -196,25 +197,38 @@ void TaskCertify::processAuthorSignature(const SignatureData &data) } } +void TaskCertify::getSignatureFiles(std::string path, SignatureFileInfoSet& file) +{ + SignatureFileInfoSet signatureFiles; + SignatureFinder signatureFinder(path); + if (SignatureFinder::NO_ERROR != signatureFinder.find(file)) { + LogError("Error in Signature Finder : " << path); + ThrowMsg(Exceptions::SignatureNotFound, + "Error openig temporary widget directory"); + } +} + void TaskCertify::stepSignature() { LogInfo("================ Step: <> ENTER ==============="); std::string widgetPath; - if (m_contextData.widgetConfig.packagingType == - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) - { - widgetPath = m_contextData.locations->getSourceDir() + "/"; - } else { - widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/"; - } + widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/"; SignatureFileInfoSet signatureFiles; - SignatureFinder signatureFinder(widgetPath); - if (SignatureFinder::NO_ERROR != signatureFinder.find(signatureFiles)) { - LogError("Error in Signature Finder"); - ThrowMsg(Exceptions::SignatureNotFound, - "Error openig temporary widget directory"); + + Try { + getSignatureFiles(widgetPath, signatureFiles); + + if (signatureFiles.size() <= 0) { + widgetPath = m_contextData.locations->getTemporaryPackageDir() + + WrtDB::GlobalConfig::GetWidgetSrcPath() + "/"; + if (0 == access(widgetPath.c_str(), F_OK)) { + getSignatureFiles(widgetPath, signatureFiles); + } + } + } Catch(Exceptions::SignatureNotFound) { + ReThrowMsg(Exceptions::SignatureNotFound, widgetPath); } SignatureFileInfoSet::reverse_iterator iter = signatureFiles.rbegin(); diff --git a/src/jobs/widget_install/task_certify.h b/src/jobs/widget_install/task_certify.h index 6c42853..955b8ff 100644 --- a/src/jobs/widget_install/task_certify.h +++ b/src/jobs/widget_install/task_certify.h @@ -25,6 +25,7 @@ //SYSTEM INCLUDES #include #include +#include //WRT INCLUDES #include @@ -54,6 +55,8 @@ class TaskCertify : void processDistributorSignature(const ValidationCore::SignatureData &data); void processAuthorSignature(const ValidationCore::SignatureData &data); + void getSignatureFiles(std::string path, + ValidationCore::SignatureFileInfoSet& file); bool isTizenWebApp() const; }; diff --git a/src/jobs/widget_install/task_file_manipulation.cpp b/src/jobs/widget_install/task_file_manipulation.cpp index fa229cd..181e85e 100644 --- a/src/jobs/widget_install/task_file_manipulation.cpp +++ b/src/jobs/widget_install/task_file_manipulation.cpp @@ -150,8 +150,7 @@ TaskFileManipulation::TaskFileManipulation(InstallerContext& context) : m_context.locationType) { AddStep(&TaskFileManipulation::StepCreateDirs); - if (m_context.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + if (m_context.mode.extension != InstallMode::ExtensionType::DIR) { AddStep(&TaskFileManipulation::StepRenamePath); AddAbortStep(&TaskFileManipulation::StepAbortRenamePath); @@ -206,17 +205,17 @@ void TaskFileManipulation::StepCreatePrivateStorageDir() LogDebug("Create private storage directory : " << m_context.locations->getPrivateStorageDir()); + changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE); + if (m_context.isUpdateMode) { //update std::string backData = m_context.locations->getBackupPrivateDir(); LogDebug("copy private storage " << backData << " to " << storagePath); - WrtUtilMakeDir(storagePath); if (!DirectoryApi::DirectoryCopy(backData, storagePath)) { LogError("Failed to rename " << backData << " to " << storagePath); ThrowMsg(Exceptions::BackupFailed, "Error occurs copy private strage files"); } } - changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE); std::string tempStoragePath = m_context.locations->getPrivateTempStorageDir(); LogDebug("Create temp private storage directory : " << tempStoragePath); @@ -253,17 +252,16 @@ void TaskFileManipulation::StepRenamePath() void TaskFileManipulation::StepLinkForPreload() { if (m_context.mode.rootPath == InstallMode::RootPath::RO) { - std::string srcDir = m_context.locations->getUserDataRootDir() + - WrtDB::GlobalConfig::GetWidgetSrcPath(); + std::string optRes = m_context.locations->getUserDataRootDir() + + WrtDB::GlobalConfig::GetWidgetResPath(); + std::string usrRes = m_context.locations->getPackageInstallationDir() + + WrtDB::GlobalConfig::GetWidgetResPath(); - if (0 != access(srcDir.c_str(), F_OK)) { + if (0 != access(optRes.c_str(), F_OK)) { LogDebug("Make symbolic name for preaload app" << - m_context.locations->getSourceDir() << " to " << srcDir); - std::string resDir = m_context.locations->getUserDataRootDir() + - "/res"; + usrRes << " to " << optRes); - WrtUtilMakeDir(resDir); - if (symlink(m_context.locations->getSourceDir().c_str(), srcDir.c_str()) != 0) + if (symlink(usrRes.c_str(), optRes.c_str()) != 0) { int error = errno; if (error) @@ -317,22 +315,18 @@ void TaskFileManipulation::StepAbortRenamePath() { LogDebug("[Rename Widget Path] Aborting.... (Rename path)"); std::string widgetPath; - if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) { - widgetPath = m_context.locations->getPackageInstallationDir(); - if (!WrtUtilRemove(widgetPath)) { - ThrowMsg(Exceptions::RemovingFolderFailure, - "Error occurs during removing existing folder"); - } - // Remove user data directory if preload web app. - std::string userData = m_context.locations->getUserDataRootDir(); - if (0 == access(userData.c_str(), F_OK)) { - if (!WrtUtilRemove(userData)) { - ThrowMsg(Exceptions::RemovingFolderFailure, - "Error occurs during removing user data directory"); - } + widgetPath = m_context.locations->getPackageInstallationDir(); + if (!WrtUtilRemove(widgetPath)) { + LogError("Error occurs during removing existing folder"); + } + // Remove user data directory if preload web app. + std::string userData = m_context.locations->getUserDataRootDir(); + if (0 == access(userData.c_str(), F_OK)) { + if (!WrtUtilRemove(userData)) { + LogError("Error occurs during removing user data directory"); } - } + LogDebug("Rename widget path sucessful!"); } diff --git a/src/jobs/widget_install/task_install_ospsvc.cpp b/src/jobs/widget_install/task_install_ospsvc.cpp index 30c8101..0ef8990 100644 --- a/src/jobs/widget_install/task_install_ospsvc.cpp +++ b/src/jobs/widget_install/task_install_ospsvc.cpp @@ -116,14 +116,7 @@ void TaskInstallOspsvc::StepUpdateManifestFile() manifest_file << ".xml"; LogDebug("manifest file : " << manifest_file.str()); - int ret = pkgmgr_parser_parse_manifest_for_uninstallation( - manifest_file.str().c_str(), NULL); - - if (ret != 0) { - LogError("Manifest parser error: " << ret); - } - - int code = pkgmgr_parser_parse_manifest_for_installation( + int code = pkgmgr_parser_parse_manifest_for_upgrade( manifest_file.str().c_str(), NULL); if (code != 0) { diff --git a/src/jobs/widget_install/task_manifest_file.cpp b/src/jobs/widget_install/task_manifest_file.cpp index d9cfeaa..99b34a1 100755 --- a/src/jobs/widget_install/task_manifest_file.cpp +++ b/src/jobs/widget_install/task_manifest_file.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -315,9 +316,10 @@ void TaskManifestFile::stepCopyLiveboxFiles() std::ostringstream targetFile; FOREACH (boxIt, liveBoxList) { - boxSizeType boxSizeList = (**boxIt).m_boxInfo.m_boxSize; + ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList = + (**boxIt).m_boxInfo.m_boxSize; FOREACH (sizeIt, boxSizeList) { - std::string preview = DPL::ToUTF8String((*sizeIt).second); + std::string preview = DPL::ToUTF8String((*sizeIt).m_preview); if (preview.empty()) { continue; } @@ -326,7 +328,7 @@ void TaskManifestFile::stepCopyLiveboxFiles() sourceFile << preview; targetFile << m_context.locations->getSharedDataDir() << "/"; targetFile << (**boxIt).m_liveboxId << "."; - targetFile << DPL::ToUTF8String((*sizeIt).first) << ".preview.png"; + targetFile << DPL::ToUTF8String((*sizeIt).m_size) << ".preview.png"; DPL::FileInput input(sourceFile.str()); DPL::FileOutput output(targetFile.str()); @@ -585,7 +587,6 @@ void TaskManifestFile::stepGenerateManifest() void TaskManifestFile::stepParseManifest() { int code = 0; - char* updateTags[3] = {NULL, }; if (!m_context.mode.removable) { @@ -595,20 +596,14 @@ void TaskManifestFile::stepParseManifest() } - if (!access(commit_manifest.c_str(), F_OK) == 0) { - commitManifest(); - code = pkgmgr_parser_parse_manifest_for_installation( - commit_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags); + commitManifest(); - if (code != 0) { - LogError("Manifest parser error: " << code); - ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code); - } - } else { - if (m_context.widgetConfig.packagingType != - PKG_TYPE_HYBRID_WEB_APP) - { - commitManifest(); + if (m_context.isUpdateMode || ( + m_context.mode.rootPath == InstallMode::RootPath::RO + && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD + && m_context.mode.extension == InstallMode::ExtensionType::DIR)) { + + if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) { code = pkgmgr_parser_parse_manifest_for_upgrade( commit_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags); @@ -616,7 +611,14 @@ void TaskManifestFile::stepParseManifest() LogError("Manifest parser error: " << code); ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code); } + } + } else { + code = pkgmgr_parser_parse_manifest_for_installation( + commit_manifest.c_str(), (updateTags[0] == NULL) ? NULL : updateTags); + if (code != 0) { + LogError("Manifest parser error: " << code); + ThrowMsg(Exceptions::ManifestInvalid, "Parser returncode: " << code); } } @@ -1149,18 +1151,17 @@ void TaskManifestFile::setLiveBoxInfo(Manifest& manifest) box.boxTouchEffect= L"false"; } - std::list > BoxSizeList - = ConfigInfo->m_boxInfo.m_boxSize; - FOREACH(im, BoxSizeList) { - std::pair boxSize = *im; - if (!boxSize.second.empty()) { - boxSize.second = + ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList = + ConfigInfo->m_boxInfo.m_boxSize; + FOREACH(it, boxSizeList) { + if (!(*it).m_preview.empty()) { + (*it).m_preview = DPL::FromUTF8String(m_context.locations->getSharedDataDir()) + DPL::String(L"/") + ConfigInfo->m_liveboxId + DPL::String(L".") + - boxSize.first + DPL::String(L".preview.png"); + (*it).m_size + DPL::String(L".preview.png"); } - box.boxSize.push_back(boxSize); + box.boxSize.push_back((*it)); } if (!ConfigInfo->m_boxInfo.m_pdSrc.empty() diff --git a/src/jobs/widget_install/task_remove_backup.cpp b/src/jobs/widget_install/task_remove_backup.cpp index 47e9cf4..e4cc1f0 100644 --- a/src/jobs/widget_install/task_remove_backup.cpp +++ b/src/jobs/widget_install/task_remove_backup.cpp @@ -42,8 +42,7 @@ TaskRemoveBackupFiles::TaskRemoveBackupFiles(InstallerContext& context) : DPL::TaskDecl(this), m_context(context) { - if (m_context.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + if (m_context.mode.extension != InstallMode::ExtensionType::DIR) { AddStep(&TaskRemoveBackupFiles::StepRemoveBackupFiles); } diff --git a/src/jobs/widget_install/task_widget_config.cpp b/src/jobs/widget_install/task_widget_config.cpp index f77a8b7..00c5fa0 100755 --- a/src/jobs/widget_install/task_widget_config.cpp +++ b/src/jobs/widget_install/task_widget_config.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -122,8 +123,6 @@ void TaskWidgetConfig::ReadLocaleFolders() return; } - - struct stat statStruct; struct dirent dirent; struct dirent *result; @@ -537,13 +536,14 @@ void TaskWidgetConfig::StepVerifyLivebox() LogInfo("livebox type: " << boxType); - boxSizeType boxSizeList = (**it).m_boxInfo.m_boxSize; + ConfigParserData::LiveboxInfo::BoxSizeList boxSizeList = + (**it).m_boxInfo.m_boxSize; char** boxSize = static_cast( malloc(sizeof(char*)* boxSizeList.size())); int boxSizeCnt = 0; FOREACH (m, boxSizeList) { - boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).first).c_str()); + boxSize[boxSizeCnt++] = strdup(DPL::ToUTF8String((*m).m_size).c_str()); } bool chkSize = web_provider_plugin_check_supported_size( diff --git a/src/jobs/widget_install/widget_unzip.cpp b/src/jobs/widget_install/widget_unzip.cpp index bcf29e8..e78cdba 100644 --- a/src/jobs/widget_install/widget_unzip.cpp +++ b/src/jobs/widget_install/widget_unzip.cpp @@ -34,6 +34,8 @@ using namespace WrtDB; namespace { +const char* const NPRUNTIME_PLUGINS_DIR = "plugins/"; + struct PathAndFilePair { std::string path; @@ -60,6 +62,34 @@ PathAndFilePair SplitFileAndPath(const std::string &filePath) position), filePath.substr(position + 1)); } + +inline bool isNPPlugin(const std::string& filePath) +{ + std::string::size_type pos = filePath.find(NPRUNTIME_PLUGINS_DIR); + // Not specified if a plug-in name MUST end with a specific extension + // (e.g. .so) + return ((std::string::npos != pos) && + ('/' != filePath[filePath.length() - 1])); +} + +// precondition: isNPPlugin(filePath) == true +inline bool isValidNPPlugin(const std::string& filePath) +{ + return (filePath.find(GlobalConfig::GetNPRuntimePluginsPath()) == 0); +} + +bool shouldBeInstalled(const std::string& filePath) +{ + if (isNPPlugin(filePath)) + { + if (!isValidNPPlugin(filePath)) + { + LogDebug("Not a valid NPRuntime plug-in: " << filePath); + return false; + } + } + return true; +} } namespace Jobs { @@ -98,44 +128,51 @@ void WidgetUnzip::unzipProgress(const std::string &destination) // Extract file or path std::string fileName = m_zipIterator->name; - if (fileName[fileName.size() - 1] == '/') { - // This is path - std::string newPath = destination + "/" + - fileName.substr(0, fileName.size() - 1); - LogPedantic("Path to extract: " << newPath); - - // Create path in case of it is empty - createTempPath(newPath); - } else { - // This is regular file - std::string fileExtractPath = destination + "/" + 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); + if (shouldBeInstalled(m_zipIterator->name)) + { + if (fileName[fileName.size() - 1] == '/') { + // This is path + std::string newPath = destination + "/" + + 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 = destination + "/" + 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); + } } } + else + { + LogDebug("Skipping file: " << m_zipIterator->name); + } // Check whether there are more files to extract if (++m_zipIterator == m_zip->end()) { diff --git a/src/jobs/widget_uninstall/job_widget_uninstall.cpp b/src/jobs/widget_uninstall/job_widget_uninstall.cpp index 986ee29..70c6340 100644 --- a/src/jobs/widget_uninstall/job_widget_uninstall.cpp +++ b/src/jobs/widget_uninstall/job_widget_uninstall.cpp @@ -28,25 +28,20 @@ #include #include #include +#include using namespace WrtDB; namespace { //anonymous const char* REG_TIZEN_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$"; const int PKGID_LENTH = 10; -const std::string PRELOAD_INSTALLED_PATH = "/usr/apps"; +const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps"); bool checkDirectoryExist(const std::string& pkgId) { - std::string installPath = - std::string(GlobalConfig::GetUserInstalledWidgetPath()) + - "/" + pkgId; - - struct stat dirStat; - if ((stat(installPath.c_str(), &dirStat) == 0)) { - return true; - } - return false; + DPL::Utils::Path installPath(GlobalConfig::GetUserInstalledWidgetPath()); + installPath /= pkgId; + return installPath.Exists(); } } @@ -106,7 +101,7 @@ JobWidgetUninstall::JobWidgetUninstall( m_context.locations = WidgetLocation(m_context.tzPkgid); m_context.locations->registerAppid(m_context.tzAppid); m_context.installedPath = - DPL::ToUTF8String(*dao.getWidgetInstalledPath()); + DPL::Utils::Path(*dao.getWidgetInstalledPath()); LogInfo("Widget model exists. App id : " << m_context.tzAppid); @@ -150,7 +145,7 @@ WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id) LogDebug("Regcomp failed"); } std::string pkgId; - std::string installPath; + DPL::Utils::Path installPath; Try { if ((regexec(®x, id.c_str(), @@ -163,16 +158,14 @@ WidgetStatus JobWidgetUninstall::getWidgetStatus(const std::string &id) LogDebug("Get appid from pkgid : " << appid); m_context.tzAppid = DPL::ToUTF8String(appid); WrtDB::WidgetDAOReadOnly dao(appid); - installPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); + installPath = DPL::Utils::Path(*dao.getWidgetInstalledPath()); } else { pkgId = id.substr(0, PKGID_LENTH); WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(id)); m_context.tzAppid = id; - installPath = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); + installPath = DPL::Utils::Path(*dao.getWidgetInstalledPath()); } - - if (0 == installPath.compare(0, PRELOAD_INSTALLED_PATH.length(), - PRELOAD_INSTALLED_PATH)) { + if(installPath.isSubPath(PRELOAD_INSTALLED_PATH)){ LogDebug("This widget is prealoded."); } } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { diff --git a/src/jobs/widget_uninstall/task_remove_files.cpp b/src/jobs/widget_uninstall/task_remove_files.cpp old mode 100755 new mode 100644 index 7404a74..4a5122f --- a/src/jobs/widget_uninstall/task_remove_files.cpp +++ b/src/jobs/widget_uninstall/task_remove_files.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -62,13 +63,18 @@ void TaskRemoveFiles::StepRemoveInstallationDirectory() { LogDebug("Removing directory"); m_context.removeStarted = true; - if (!WrtUtilRemove(m_context.installedPath)) { + DPL::Utils::Path widgetDir= m_context.installedPath; + Try{ + DPL::Utils::Remove(widgetDir); + } Catch(DPL::Utils::Path::BaseException){ LogError("Removing widget installation directory failed : " << - m_context.installedPath); + widgetDir.Fullpath()); } - std::string dataDir = m_context.locations->getUserDataRootDir(); - if (!WrtUtilRemove(dataDir)) { - LogWarning(dataDir + " is already removed"); + DPL::Utils::Path dataDir(m_context.locations->getUserDataRootDir()); + Try{ + DPL::Utils::Remove(dataDir); + } Catch(DPL::Utils::Path::BaseException){ + LogWarning(dataDir.Fullpath() << " is already removed"); } } else { LogDebug("Removing sdcard directory"); @@ -105,32 +111,33 @@ void TaskRemoveFiles::StepRemoveManifest() { std::ostringstream manifest_name; manifest_name << m_context.tzPkgid << ".xml"; - std::ostringstream destFile; - const std::string PRELOAD_INSTALLED_PATH = "/usr/apps"; - if (0 == (m_context.installedPath).compare(0, PRELOAD_INSTALLED_PATH.length(), - PRELOAD_INSTALLED_PATH)) { - LogDebug("This widget is prealoded."); - destFile << "/usr/share/packages" << "/"; //TODO constant with path + DPL::Utils::Path destFile; + const DPL::Utils::Path PRELOAD_INSTALLED_PATH("/usr/apps"); + const DPL::Utils::Path USR_PACKAGES_PATH("/usr/share/packages"); + const DPL::Utils::Path OPT_PACKAGES_PATH("/opt/share/packages"); + if (0 == (m_context.installedPath.Fullpath()).compare(0, + PRELOAD_INSTALLED_PATH.Fullpath().length(), + PRELOAD_INSTALLED_PATH.Fullpath())) { + LogDebug("This widget is preloaded."); + destFile = USR_PACKAGES_PATH; } else { - destFile << "/opt/share/packages" << "/"; //TODO constant with path + destFile = OPT_PACKAGES_PATH; } - destFile << manifest_name.str(); - std::string pre_manifest = "/usr/share/packages/" + manifest_name.str(); + destFile /= manifest_name.str(); + DPL::Utils::Path pre_manifest = USR_PACKAGES_PATH; + pre_manifest /= manifest_name.str(); - if (!(access(destFile.str().c_str(), F_OK) == 0 && - access(pre_manifest.c_str(), F_OK) == 0)) { + if (!(destFile.Exists() == 0 && pre_manifest.Exists())) { int ret1 = pkgmgr_parser_parse_manifest_for_uninstallation( - destFile.str().c_str(), NULL); + destFile.Fullpath().c_str(), NULL); if (ret1 != 0) { LogWarning("Manifest file failed to parse for uninstallation"); } } - - int ret2 = unlink(destFile.str().c_str()); - if (ret2 != 0) { - LogWarning("No manifest file found: " << destFile.str()); + if (!DPL::Utils::TryRemove(destFile)) { + LogWarning("No manifest file found: " << destFile.Fullpath()); } else { - LogDebug("Manifest file removed: " << destFile.str()); + LogDebug("Manifest file removed: " << destFile.Fullpath()); } } @@ -140,25 +147,28 @@ void TaskRemoveFiles::StepRemoveExternalLocations() WidgetDAO dao(DPL::FromUTF8String(m_context.tzAppid)); LogDebug("Removing external locations:"); WrtDB::ExternalLocationList externalPaths = dao.getWidgetExternalLocations(); - FOREACH(path, externalPaths) + FOREACH(file, externalPaths) { - if (WrtUtilFileExists(*path)) { - LogDebug(" -> " << *path); - 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)) { - LogDebug(" -> " << *path); - if (!WrtUtilRemove(*path)) { - Throw( - Jobs::WidgetUninstall::TaskRemoveFiles::Exception:: - RemoveFilesFailed); + DPL::Utils::Path path(*file); + if(path.Exists()){ + if(path.IsFile()){ + LogDebug(" -> " << path.Fullpath()); + Try{ + DPL::Utils::Remove(path); + }Catch(DPL::Utils::Path::BaseException){ + LogError("Failed to remove the file: " << path.Fullpath()); + } + } else if (path.IsDir()){ + LogDebug(" -> " << path.Fullpath()); + Try{ + DPL::Utils::Remove(path); + }Catch(DPL::Utils::Path::BaseException){ + Throw(Jobs::WidgetUninstall::TaskRemoveFiles:: + Exception::RemoveFilesFailed); + } } - } else { - LogWarning(" -> " << *path << "(no such a path)"); + }else{ + LogWarning(" -> " << path.Fullpath() << "(no such a path)"); } } dao.unregisterAllExternalLocations(); diff --git a/src/jobs/widget_uninstall/uninstaller_context.h b/src/jobs/widget_uninstall/uninstaller_context.h index 3d9fe28..25c25e3 100644 --- a/src/jobs/widget_uninstall/uninstaller_context.h +++ b/src/jobs/widget_uninstall/uninstaller_context.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace Jobs { namespace WidgetUninstall { @@ -62,7 +63,7 @@ struct UninstallerContext std::string tzAppid; std::string tzPkgid; bool removeAbnormal; - std::string installedPath; + DPL::Utils::Path installedPath; }; #endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_ diff --git a/src/logic/installer_logic.cpp b/src/logic/installer_logic.cpp index 10cda89..6b3f06c 100644 --- a/src/logic/installer_logic.cpp +++ b/src/logic/installer_logic.cpp @@ -29,12 +29,12 @@ using namespace WrtDB; namespace Logic { InstallerLogic::InstallerLogic() : - m_NextHandle(0) + m_NextHandle(0),m_job(0) {} InstallerLogic::~InstallerLogic() { - Assert(m_jobs.empty() && "There are still running jobs"); + Assert(!m_job && "There are still running job"); //FIXME what should be done here? } @@ -46,24 +46,19 @@ void InstallerLogic::Initialize() void InstallerLogic::Terminate() { //TODO how to delete, if it is still running, paused and so on - FOREACH(it, m_jobs) - { - it->second->SetPaused(true); //FIXME this is not enough! - } + if(m_job) + m_job->SetPaused(true); LogDebug("Done"); } -Jobs::JobHandle InstallerLogic::AddAndStartJob(Jobs::Job *job) +Jobs::JobHandle InstallerLogic::AddAndStartJob() { Jobs::JobHandle handle = GetNewJobHandle(); - job->SetJobHandle(handle); - - m_jobs.insert(std::make_pair(handle, job)); - + m_job->SetJobHandle(handle); //Start job CONTROLLER_POST_EVENT(InstallerController, - InstallerControllerEvents::NextStepEvent(job)); + InstallerControllerEvents::NextStepEvent(m_job)); return handle; } @@ -75,12 +70,19 @@ Jobs::JobHandle InstallerLogic::InstallWidget( const WidgetInstallationStruct & installerStruct) { + if(m_job) + { + LogError("Job is in progress. It is impossible to add new job"); + return -1; + } + LogDebug("New Widget Installation:"); - Jobs::Job *job = + m_job = new Jobs::WidgetInstall::JobWidgetInstall(widgetPath, installerStruct); - return AddAndStartJob(job); + + return AddAndStartJob(); } Jobs::JobHandle InstallerLogic::UninstallWidget( @@ -88,13 +90,19 @@ Jobs::JobHandle InstallerLogic::UninstallWidget( const WidgetUninstallationStruct &uninstallerStruct) { + if(m_job) + { + LogError("Job is in progress. It is impossible to add new job"); + return -1; + } + LogDebug("New Widget Uninstallation"); - Jobs::Job *job = + m_job = new Jobs::WidgetUninstall::JobWidgetUninstall(widgetPkgName, uninstallerStruct); - return AddAndStartJob(job); + return AddAndStartJob(); } Jobs::JobHandle InstallerLogic::InstallPlugin( @@ -102,14 +110,23 @@ Jobs::JobHandle InstallerLogic::InstallPlugin( const PluginInstallerStruct & installerStruct) { + if(m_job) + { + LogError("Job is in progress. It is impossible to add new job"); + return -1; + } + LogDebug("New Plugin Installation"); - Jobs::Job *job = - new Jobs::PluginInstall::JobPluginInstall(pluginPath, installerStruct); + //Conversion to DPL::Utils::Path is temporary + m_job = + new Jobs::PluginInstall::JobPluginInstall(DPL::Utils::Path(pluginPath), installerStruct); + // before start install plugin, reset plugin data which is stopped // during installing. (PluginDAO::INSTALLATION_IN_PROGRESS) ResetProgressPlugins(); - return AddAndStartJob(job); + + return AddAndStartJob(); } #define TRANSLATE_JOB_EXCEPTION() \ @@ -148,8 +165,8 @@ bool InstallerLogic::NextStep(Jobs::Job *job) } //clean job - m_jobs.erase(job->GetJobHandle()); delete job; + m_job=0; return false; } catch (Jobs::JobExceptionBase &exc) { @@ -165,8 +182,8 @@ bool InstallerLogic::NextStep(Jobs::Job *job) job->SendFinishedFailure(); //clean job - m_jobs.erase(job->GetJobHandle()); delete job; + m_job=0; } return hasAbortSteps; } diff --git a/src/logic/installer_logic.h b/src/logic/installer_logic.h index 496e967..0d3463e 100644 --- a/src/logic/installer_logic.h +++ b/src/logic/installer_logic.h @@ -27,8 +27,7 @@ namespace Logic { class InstallerLogic { - typedef std::map JobsContainer; - JobsContainer m_jobs; + Jobs::Job* m_job; void ResetProgressPlugins(); void InstallWaitingPlugins(); @@ -39,7 +38,7 @@ class InstallerLogic { return m_NextHandle++; } - Jobs::JobHandle AddAndStartJob(Jobs::Job *job); + Jobs::JobHandle AddAndStartJob(); public: virtual ~InstallerLogic(); diff --git a/src/misc/widget_location.cpp b/src/misc/widget_location.cpp index 4c93057..71f8b28 100644 --- a/src/misc/widget_location.cpp +++ b/src/misc/widget_location.cpp @@ -62,12 +62,14 @@ WidgetLocation::~WidgetLocation() WidgetLocation::WidgetLocation(const std::string & widgetname, std::string sourcePath, WrtDB::PackagingType t, - bool isReadonly) : + bool isReadonly, + InstallMode::ExtensionType eType) : m_pkgid(widgetname), m_widgetSource(sourcePath), m_type(t), m_temp( - new WidgetLocation::DirectoryDeletor(isReadonly)) + new WidgetLocation::DirectoryDeletor(isReadonly)), + m_extensionType(eType) { if (isReadonly) { m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath(); @@ -84,11 +86,13 @@ WidgetLocation::WidgetLocation(const std::string & widgetname, std::string sourcePath, std::string dirPath, WrtDB::PackagingType t, - bool isReadonly) : + bool isReadonly, + InstallMode::ExtensionType eType) : m_pkgid(widgetname), m_widgetSource(sourcePath), m_type(t), - m_temp(new WidgetLocation::DirectoryDeletor(dirPath)) + m_temp(new WidgetLocation::DirectoryDeletor(dirPath)), + m_extensionType(eType) { if (isReadonly) { m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath(); @@ -187,7 +191,7 @@ std::string WidgetLocation::getTemporaryPackageDir() const std::string WidgetLocation::getTemporaryRootDir() const { - if (m_type == WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) { + if (m_extensionType == InstallMode::ExtensionType::DIR) { return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath(); } if (m_type == WrtDB::PKG_TYPE_HYBRID_WEB_APP) { @@ -206,8 +210,6 @@ std::string WidgetLocation::getConfigurationDir() const path = m_widgetSource.substr(0, index); } return path; - } 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 2b44d4d..c3f8c39 100644 --- a/src/misc/widget_location.h +++ b/src/misc/widget_location.h @@ -26,6 +26,7 @@ #include #include #include +#include /** * @brief The WidgetLocation class @@ -101,12 +102,16 @@ class WidgetLocation */ WidgetLocation(const std::string & widgetname, std::string sourcePath, WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP, - bool isReadonly = false); + bool isReadonly = false, + InstallMode::ExtensionType eType = + InstallMode::ExtensionType::WGT); WidgetLocation(const std::string & widgetname, std::string sourcePath, std::string dirPath, WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP, - bool isReadonly = false); + bool isReadonly = false, + InstallMode::ExtensionType eType = + InstallMode::ExtensionType::WGT); ~WidgetLocation(); @@ -215,6 +220,7 @@ class WidgetLocation std::shared_ptr m_temp; //directory WrtDB::ExternalLocationList m_externals; std::string m_installedPath; + InstallMode::ExtensionType m_extensionType; }; #endif // WRT_INSTALLER_SRC_MISC_WIDGET_LOCATION_H diff --git a/tests/general/CMakeLists.txt b/tests/general/CMakeLists.txt index 8e67a1a..0eca7ea 100644 --- a/tests/general/CMakeLists.txt +++ b/tests/general/CMakeLists.txt @@ -66,6 +66,7 @@ SET(INSTALLER_TESTS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NonRootUserTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/NPluginsInstallTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ParsingTizenAppcontrolTests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/WidgetUpdateTests.cpp ) SET(INSTALLER_TESTS_TARGET "wrt-installer-tests-general") @@ -129,13 +130,6 @@ target_link_libraries(${INSTALLER_TESTS_TARGET} ) #widgets -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/manifest.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/bg-00-with_bg.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/bg-01-missing_file.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/bg-02-without_bg.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/nonroot.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_1.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_2.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_3.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/inst_nplug_4.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/widgets/app-control.wgt DESTINATION /opt/share/widget/tests/installer/widgets/) +FILE(GLOB files "${CMAKE_CURRENT_SOURCE_DIR}/widgets/*.wgt") +INSTALL(FILES ${files} DESTINATION /opt/share/widget/tests/installer/widgets/) + diff --git a/tests/general/WidgetUpdateTests.cpp b/tests/general/WidgetUpdateTests.cpp new file mode 100644 index 0000000..064e545 --- /dev/null +++ b/tests/general/WidgetUpdateTests.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file WidgetUpdateTests.cpp + * @author Grzegorz Rynkowski (g.rynkowski@samsung.com) + * @version 1.0 + * @brief Test a process of updating web applications. + */ + +#include +#include +#include +#include + +using namespace InstallerWrapper; + +#define RUNNER_ASSERT_MSG_SAFE(test, message) \ + { \ + DPL::Test::TestRunnerSingleton::Instance().MarkAssertion(); \ + \ + if (!(test)) \ + { \ + uninstall(tizenId); \ + std::ostringstream assertMsg; \ + assertMsg << message; \ + throw DPL::Test::TestRunner::TestFailed(#test, \ + __FILE__, \ + __LINE__, \ + assertMsg.str()); \ + } \ + } + +RUNNER_TEST_GROUP_INIT(WidgetUpdate) + +/* +Name: validUpdateOfSigned +Description: Tests update the web app where origin and a new one are signed. +Expected: Widget should be successfully installed. +*/ +RUNNER_TEST(validUpdateOfSigned) +{ + std::string tizenId; + std::string wgtPath; + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt"; + RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success, + "Failed to install widget"); + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt"; + RUNNER_ASSERT_MSG_SAFE(install(wgtPath, tizenId) == InstallerWrapper::Success, + "Failed update in case both programs are signed"); + uninstall(tizenId); +} + +/* +Name: validUpdateOfUnsigned +Description: Tests update the web app where origin and a new one are unsigned. +Expected: Widget should be successfully updated. +*/ +RUNNER_TEST(validUpdateOfUnsigned) +{ + std::string tizenId; + std::string wgtPath; + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt"; + RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId), + "Failed to install widget"); + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt"; + RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success == install(wgtPath, tizenId), + "Failed update in case both programs are signed"); + uninstall(tizenId); +} + +/* + * Information: + * These tests are incompatible to the specification 2.1 + * (but compatible to the specification 3.0). + */ +///* +//Name: unupdateOfSigned +//Description: Tests update that signed web app could be downgraded. +//Expected: Widget should not be updated. +//*/ +//RUNNER_TEST(unupdateOfSigned) +//{ +// std::string tizenId; +// std::string wgtPath; +// +// wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt"; +// RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId), +// "Failed to install widget"); +// +// wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt"; +// RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId), +// "Unupdate should be prohibited."); +// uninstall(tizenId); +//} +// +///* +//Name: unupdateOfSigned +//Description: Tests update that unsigned web app could be downgraded. +//Expected: Widget should not be updated. +//*/ +//RUNNER_TEST(unupdateOfUnsigned) +//{ +// std::string tizenId; +// std::string wgtPath; +// +// wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt"; +// RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId), +// "Failed to install widget"); +// +// wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt"; +// RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId), +// "Unupdate should be prohibited."); +// uninstall(tizenId); +//} + +/* +Name: validUpdateOfCrossSigned +Description: Tests update the web app where one of widgets are signed and second not. +Expected: Widget should not be updated. +*/ +RUNNER_TEST(updateOfCrossSignedWidgets) +{ + std::string tizenId; + std::string wgtPath; + + { + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Unsigned.wgt"; + RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId), + "Failed to install widget"); + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt"; + RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId), + "The update unsigned app by the signed app should not be possible"); + uninstall(tizenId); + } + { + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt"; + RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId), + "Failed to install widget"); + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Unsigned.wgt"; + RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId), + "The update signed app by the unsigned app should not be possible"); + uninstall(tizenId); + } +} + + +/* +Name: updateAnotherAuthor +Description: Tests update the web app by the widget signed by another author. +Expected: Widget should not be updated. +*/ +RUNNER_TEST(updateAnotherAuthor) +{ + std::string tizenId; + std::string wgtPath; + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt"; + RUNNER_ASSERT_MSG(InstallerWrapper::Success == install(wgtPath, tizenId), + "Failed to install widget"); + + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220SignedAnotherAuthor.wgt"; + RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success != install(wgtPath, tizenId), + "The update by another author should not be possible"); + uninstall(tizenId); +} + + +/* +Name: updateWidgetDataRemember +Description: Tests of keeping app data during widget updating. +Expected: App data should be kept. +*/ +RUNNER_TEST(updateWidgetDataRemember) +{ + std::string tizenId; + std::string wgtPath; + + // Installation of the widget + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer100Signed.wgt"; + RUNNER_ASSERT_MSG(install(wgtPath, tizenId) == InstallerWrapper::Success, + "Failed to install widget"); + + // Creating a file + std::string filePath = "/opt/usr/apps/HAdisUJ4Kn/data/test"; + std::string text = "slonce swieci dzisiaj wyjatkowo wysoko"; + std::string command = "echo " + text + " > " + filePath; + system(command.c_str()); + + // Second installation of the widget + wgtPath = miscWidgetsStuff + "widgets/widgetUpdateVer220Signed.wgt"; + RUNNER_ASSERT_MSG_SAFE(InstallerWrapper::Success == install(wgtPath, tizenId), + "Failed update in case both programs are signed"); + + + // Checking of the file created before + std::stringstream ss; + std::ifstream file(filePath); + RUNNER_ASSERT_MSG_SAFE(file.good(), "File is gone"); + + for( std::string line; getline( file, line ); ss << line); + file.close(); + RUNNER_ASSERT_MSG_SAFE(text == ss.str(), "Content of file is not the same"); + uninstall(tizenId); +} diff --git a/tests/general/widgets/widgetUpdateVer100Signed.wgt b/tests/general/widgets/widgetUpdateVer100Signed.wgt new file mode 100644 index 0000000000000000000000000000000000000000..b3ff8bf9baee12ab28a032b75e7bb4b0e53fb78d GIT binary patch literal 23379 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 b%vAF~C5whKGRoig$S=?97s*3v_;>VQtZye? literal 0 HcmV?d00001 diff --git a/tests/general/widgets/widgetUpdateVer100Unsigned.wgt b/tests/general/widgets/widgetUpdateVer100Unsigned.wgt new file mode 100644 index 0000000000000000000000000000000000000000..751aed0c21f8ef60c876f2637f71ee57e97db9b7 GIT binary patch literal 19629 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 E7Y=I_tN;K2 literal 0 HcmV?d00001 diff --git a/tests/general/widgets/widgetUpdateVer220Signed.wgt b/tests/general/widgets/widgetUpdateVer220Signed.wgt new file mode 100644 index 0000000000000000000000000000000000000000..5ef42af1fc177f87afd2b366d3a1cea279a29220 GIT binary patch literal 23398 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 literal 0 HcmV?d00001 diff --git a/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt b/tests/general/widgets/widgetUpdateVer220SignedAnotherAuthor.wgt new file mode 100644 index 0000000000000000000000000000000000000000..c1aeaa343ac08f3ec082b5199a19deaf13588bfd GIT binary patch literal 23430 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

toxC1Pz9xbjIB| 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 literal 0 HcmV?d00001 diff --git a/tests/general/widgets/widgetUpdateVer220Unsigned.wgt b/tests/general/widgets/widgetUpdateVer220Unsigned.wgt new file mode 100644 index 0000000000000000000000000000000000000000..181447de51b15364ce913f507e836de4dd037ff2 GIT binary patch literal 19647 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 Z-Ld)eaM%OcIgWN@Jshu&<|{|5{{nI5AcX(` literal 0 HcmV?d00001 diff --git a/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt b/tests/general/widgets/widgetUpdateVer220UnsignedDifferentId.wgt new file mode 100644 index 0000000000000000000000000000000000000000..8fb6c19a598415bddac21c1209651cfed23803b5 GIT binary patch literal 19649 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 literal 0 HcmV?d00001 -- 2.7.4