r-8)*fnX-cZA#9r>qKC$8%H_?rL|cS+Rc}+#aC*CT
zyVNU3BbY+T7r@+Qfi69{AlEKb`?q53bM>naq`MA-Di7?8Cz=|eeq?M0Rp_hNR
z+HL7@oZD$ryX_Gx)=fWZ%|5&+Ox*ta2d@D$iAOyRNbh5553GFxAbrDJms}8mL~o}K
zdMCY~=@(;R5Yf@eo`iJ$`t|c8mFXFN>8UmlQU*F}E@>`Xn8I<;Lyy7Y)1oQ#1?@+&
z*_17}vtr2?sNzE&&f5)xm{T1-5lc(YkfyTKjhBNLv)i|n@AV_q8ee3iEd!b94({hbRI(G>f1&UHqN<_Jl$5CJg93kXtT;sF^t9f3_2?c|H$6AQ-
zC*Z<3d2+}FD0E~NvBUL>vdB_7Lb*_;Xp|REd>kINA(Thwu!qA7tql)G8>NKAokq-t
zSx!PpV;JSB5n;Y)8TRr>-ziVHH(FlgN(|UUdygb~*M-qZJO-*YI05hsOr~2O0=DJj
z6KoW(v`+-*WY|M!yVrV_
z=?KgOY?xSE(T`arv>7@AylAp7bmHO66!M4ykWG&dkW&GqQk)um@epGX&o(uq*|kSE987e)s44iW80;Ino;uUJL<^2iii%
zLB$CtoZ#Ml_gybnmmjo)wzIRw0We33fCN}?zx}owHoc+i&~&BiZF=@^TitbSUflqT
z-Y?2ZXJ&}5Sy=+ufYDjdgE*mViC)x4h!dR1Q3QoNz3tk4^!XnZ^pUK+26Rs+8yPVl~;3{%5vOyyAs?s12M_|v}JCR
zUHsdtVD)NeyDp9Dxo*v>xZbU++f(OzHxy+h_C$aQw(sFueNhdeK4D`O=LP^%D*6Kg
zvkxOS+$2fYbIv)(KQGJ_iSgiPG|3k5(NQ_IV!fsAwYlwGc8w}-(&_>?asFa=_oyYV
zeZxwwXUl5t*!HztzjpjZsa#i7xZ7pe?7}9FQLfIS8IUv{nF3IH5z-zU`S{Q&Egte>
zc-f*Afok2wEr%F-F`@)?fgLXhKIOrO<2DzYkA(6fw{hu2ai4u4CIauGF5@Ey=8I
zH0gX;FgKs7EU{L=2r>c=<6ZuQbO;?zq$gkd`5=Q4&fVT}lMrw0R;bc0`U
z!W(bA(VchRd49U11F#m#@S$wt)L-7HgG)$HbG0+mT|%vF8`WiQ#->6y?Vros!(s
zfi`llAK1VRI4Ik7Xk5#!S=+$h>*QKpQ?TR;%+RLFQz+Y#Mqkp>A3G>+WbCrc*vkA7
zlKolBde)ndR{ExTZTA4NzRxaLL2Qg*x!aKwm~Nnpp0`T1KdfLQ+P^t&uViH8*c4qY%cWD%c6tfkc-Emi@Yb;4|U^255q7I9@6#(9N&Z(X%DYW_n_L}jVZCu
z%U-It%U}!}9vXtUfE0)dRfh8L&=VOw>@F+kWVyKu7Q5wZzq7|so!hw89_z4UiX?k1
z)in3Ys~*bZXb3L85uO#Hl3ni2C8e%+UWTiZR_4B*
z_DzLe*h^0OE3LNv)U-MVwzjt4YG>Z-?Te}9<@Pk);*!#m0vaDyLYzt{sKQjHv_g1f
zAo68Q;y4V(LtBj69lHzsMfvR6v;7ke-24W3Mgzt}htQz|@+3b@i^h`@T;t~D2>#pcg9zP+KnMrk9h#K0>xUt(WliPEX|%?FF8rMg1fSh?&B
zSFNdi?$0K|(tV>
z`Gox_Pi@4;<`$Xv^SO2?hH1$(6W9*rB@9j+4UVTl$0!&~`BIWJj!^mJAsa(+UzAZx
zdd!$H{-U01MW#WfNG>68OoKQ9hz^QFN9KbMKInTZGXZ%x_{2*GQJc^Q9`Q*}(fGS;
z7him_8$Nuv*PY86^rxO}b=tb3tmvktuOV`)>afEO^N00ZQ$iQel{vONs2j-CO-zP{of0*CG7MJwE1ET
z=iUjqW$x1*iEc>$6WyFo-tl0?Mwg`dy68aYfSx#b(4G3_$b%NPi8`#T;kWNdE!(_l
z(+BoNmJ$>owY}Q*Y(ixSUmGW36yH|ka@eoEW
z2LL!Vma|
zwc(7Ghs^{o`8W@Zg~Nso^I&U~`pj59apY4c9S4V6v;%!`((6FsJ$K#Zet+eao{w)1
zCuUai@8GL_e129fB~-KZwKaQ*)#t;{h-GKIDJ##%(T#Ogve1Wip|5E0NLTVjCoTs+
z1IaqwEPIM@i_yJGnttIcwH@%d%%qGCtV5wd3JV12q;aYUg+jo{g9lz26&em&$O|8G
z*l_|VhvE1yzx>iqgFK$e2C8x6CieZJs{Tcz`)njJnpsEVN9DhaT#9KZnDNEseX|hpt#o;1-y4VA3&5TAZXO1#yk+QX8#BnU!57TT)76
zyL8!+`eiTVNe}EoTzRrLG&yD<+t`h_bj2vy2UP3z&)aKpe4EFf3*NgqB90)0$|F?9
zpi(IaT~7H*6RNxvi!aB92@tiBV$`l!zRVrb{V>;~O*8km4<`C!H?Bw3SjmmAhcxxz
zciE0MHN}j_*V1CN9||dZ?X}ms$usA<`SztW|K^%aG#)q)8itL~gNE~AkO%0>D@e1?
z*cySUTr-Adz<97^6Z9jG(8~|(Pg(41e-)#A=gwWvTmF7QEuTMc-a>mCZh@^)EfFl?
z3gbb74oyn=nu8xdLTq}#g*@?!k}t)HGgGi;ax0AE#sv!(xtTL(xrb^ua*J#V+t}#>
zn@epY5xZyWKViqIlz+rG}V
zKBS8qYtM7ptAh4NVysg`kAbC87y%dMS(P!TksSeBU?$Jl^_`sw7x+B@)9-Q`>sC!<}n%Cp_FlZW{!+?1=Z
zo^QGRL>7qY9upQbO9gL&P2Z{O*Vt)$bdQ&{5Jy`DB5g(|<&h5!Cp(ibXE*_^zb^
zD^kNE6`;l#OKq)sJT)!tI@jUA*{-C~LDqh1His=@g)Qn`G;)oOVzGSXu_kBk
zSnEn{wqVmo{j`lR)J672pyHv;iQ_3#Y@emGPXCy(R!qH=+Xqx*wlA_JY_N^Wcr(ZV
z3di>%3W-J>9vsHPQCWPxKq6l~PyF#T%6o;)xEL7zlBS(pV(&BkO?LPr9t#DmZGZre
zO;Gf)ji_Vs5lFtffU5{&dU|5)M_|%<_?v6oisKp>hYq*~Z{6Mt%)^4jE
zR0S<&h%8|`M3E>oHfEKYc2!np5540glep}G9c2^I6p}}qLr2;$9dG(>Kunmo52&$>
z65CBZWTSNeT2YaJix&((`BH{-$U`|s9Lf=AgopVm7f#P=2&XRaCZ?vl;&bou7NcF>
zQ%|fe)6PDWGqb>CG;7bD6~e?8PN%5b4J)EwIbXfyFK?JmBcEtfv~8lyr&?Wm>5AJEhIToVFmKX6oj=khvSk>@
zR-q>^w3*W2V+Z)-EWOVtCI5RP)r@JjNGP_E@@QgG(v$YAi|?sw9EEVCF^u8@&=X?$
ziW5rFkQN_@hY^ZgI!D4`$Jv)CI{InXV`l{-Y#4X+|0qo!0P-a=WJF&ki$cGq+P%h9
zzRPM(qk+-MG{}3Z8ll`|;4M22Lo`K(?V=M@n)s3{Yu3q?)ylJu=S4=-t{}PCQpb(Bz7KH72ahm_+5S-@u{OlCfFpAI8>!@!+Dp4H6z$o=b0JJf;(P2=U~{)51LEV`$bjWS7;>cS)ySk9c3d2he^1uwtaf(&Uj5eTfV(
zZG%S|fH|kLQB*lCYO3nsT9~zS=FFM?wjIE73B{cxc%&b?$TLNAB$@K}oA?`;u@P!v
zI6{eAy^P$7QCqm(KC#2MEuw=2wO6*0{Rr{YCmV-0r=yW)ooj*J-Fm@Vz0U>-GvM|M
zstE>tJL508M{5!5o<^HODWOpGut)h?><1n-LbNa>pDB-!hGbp-a5NGD&KTL~AeXoW
zQCw*WGK2E%T@R=km8rMLu3xil{%cf)NvXuIot#E-50(eHM~@!uM<$m|j9Ti)`MQuF
z=K;2gO{d8(-{E)09=zmes%58~VsRf@+)v8}aMGL!el0~7P94T4Vn5U?51--+VUsS_
z>1>n1Sw>9Rm<$E`1vQpgYQ6Z?l9J-D!%G+`rV2u^C6rM401c1Ip@;HBgP&;^M}u?D
z`GZT$@$b(XFS2}A4A2;`MuJSru=5E&Au~FS;DNP*yY`g12368rp8b`IBKw;$Tz_)8
z!U$!DtBsHVML!vxc)Ujw%2ZxsBX8EH(J1vJ)2=VAUS7fUe;6SaXSBN66Dd~V;yX8;
zSWfoAZa9V5inxu|FKo~As%7mh~Ld~Z!vmI*hz__g&019hwk^tGS>6;L@ODWP(N
zAy~wfR!F0CuM~c!733l-?ckm+z1wmAc_1t5K})cc9J7%J*W>49Ml`fauy=2umviES
zZZVJSQu`8Uqk8tYZIX-Kf+gSDBQ=Zs8p?fKZXmD$!iNt1)HdRwgO0w0g)iLUD&@C!
z2~}!ED}2Q|N@s{ll@-}d|M^o~5|6!@EZQg+pN5W&LXhE+4XtdEbtu-P1CCN;{Ln}x
zpPlgJJw-)tQW5jHCt5{R22FJG!i}+Ck-F@tZ&52>`q9v%O3D`01`lY
zFoD+M&?-W>AP|t}<3s>AMxd}gQgTSWG`DNxN;hrBEH`D!6#pFw9ya5&iYZ@4Q>dAR
zH1TjY5)b;48omN-H8tT{6Xieo)b?F9ZC{r@f9gyV(vhoRW3e83@*gk;o
z3GLg{JlEcz9|YAZqgxekSik=FCXkEViV9RwsDNlPgz~}$scJPu>nQ0u*VsC0?FiRT
zK%!}k#Yi4HM0(hTlJAv19TV)QU?Tu*L9sn~P%YcFOW)`|`{HYVo;B
zr*@F1HZU^rO4BBEubya!B>x;yv5qqRde8c5@siKp^VjF_Q(mEDk!E>Qs5(`j^6WjC
zwe}9~4VM3dqm=SL2r3L_>@r(#Hd`6Sda;uuwY
zHBY_VrRN_M1JKIHWO(3Wz%uYi`#hg7a0wxp$5}|as4&$HsA)Uat&811?CuWhCP#Ga
za2XZxo}#ozBS!Hs4NY`r9e_>za+E7yHq(z(ZIT$ZNqg*-%LP*r>&y5^>__b;#3?N>
zL%L;`+v(At>{4sH)%}B`6j?tCDoo}|Z43Rpf$$CqRV*M0L!|&R-V0FmJPdLN`9_Gq^y7Fhrp9j%ExMena@Rd&nH&Dee_ge1-P((d^rO?RFK9nM2~?P^5)S*f+In=M#osqW_y>nj
z2BRFv(EtpJ3wcqR#X$in&Lq?r=oI>L0g)VYo92)7ctkTLO9s#Sm4|-lD<0CJgO9wB
zpL{^U(|Hp}0_9#H6X1f!Rm-haa0R>e=6cBQL5C=m5r
z5q>PRN*R_Z_RYYjY}0YJjDQ@xlqJMNLvh~N=BYq7Dk=6^*~M$t+Fxa==IUK_mmL;l
z`Fo+fdCsTqz^KGdf{6322v0XT#r9cJfaE>bVzU@w(7ROuGl%9ED{mkNer6`a%Y*DV=UF)xKw&j(%#q6ebKSBhII2XoQTwI;%%N
zHIh_b@?v!n>|+elG#t4R2}`umSIJ(X
z_{fy$Oc`Xw%Oj1lfJ*Phljb@Rh4S+9_L=ga$%lFfX!4LL9y$cm9+wuJ3=xti7q5@#
zKNS8@`LKRuOTI$n#?zIjk*T&w2k4^N#%Rjw)vE^DF8wE6zJ$6;-oG_cD+(thB-v40
zReKnFtc}=q&{0s05FeqG7L9b+7&VxDKu6h7VWp9+xMYQ)@EoIP%3$s0NDpLu6t^bsE(n5a2yf`FMJKTJ;Dd
z(yB{&Y9DmP4==aP%^}$Q2B%*2&Bam)&c!MP5_}dWkY$&lO6&Ry7yP2&&gegBgi2S{t2E&+0;(5ez}gy{W8l7K$_@w{K|T$VF+)X&hiQ0m
zG+J~TuQ+*OoHP#E(8F@#BUIfHcl3)+;wO{~`NbnZkOQyyp{pLzkRyK4lva6o$g@q+
z$98OanysNbEd8?pMTY7oF87Opia@Kt{*Z4cW6%zuM9F0}O
zp@quI5SpS@=7&O+C!~Dn!g}KMA{~~cTsU=ya)?V7q3RKhe90G0`dFIl(C6%~%jI?n
z^rO36WbMyM*D&uF1r@1|@bOT=FfL=M0O?Sc=#<$X
zUHJ;(k$lDXSC%}1p|WA9x)dreJ`Ek3IBF8VC((5ItTEMwxg+k|%noWK3p7S<*64C@;Rufzm3YeCmvM@BpYl
zjqh0ES3YUU32D$NtM*&oO1sg0p^eZ_EsHlIe(*Y!@;~HMXUOxbfJy~c8J0@27o95G
zCC^hfb)IOA^Yzi_P?-b8WqcWww0Ma_S6YoyI^98#-M+l(g*@40a+YsG0bLNa^jr<=?
zx5y2h+OQ7|<$i5v75h)FT5s3%*4E!ev`3XLRvC?=&9O5ZR~{Dc@Xo)ab&y4LC9i7xGCmoe0{MD!5urgm^q=g69ZU~%imq0h0
zFZ2!4Ot9BIRaYKmR{oN3@*X{2^C5O$DP8HE&8W8hI-bfv}r
zLm?dqClFOubrXh8^{FoLS^1eJ>rn&qMdJs|Uwo2!1ic#Vf?b-djrddQ~P
z@y7aJ0~5V)`)m9EIjE6pUO5nCT29W(%d2Uh+WEa1@I+I(nS~L$K_g`J5D3ZoPeU1s
z5cx_Y*XlJ=`63J7wzuLQTfTfbkIwQS&96GmQuqE`sGIVCGoVT#LQ@oQnVOTEHf`F%
zHdQ=f(Z}d*jOItM8iUb8Z}}A?4*G$d%7-CwdC7^%U_{O~AjjFw?|;~{!}Bd4Aemyn
zzb!scrN07Q`iG)_lb}jLQd`!VcPK4UMIq`6?FY>(F@k_}g5RW$5yke+hYkW}9Kd?XEQzUukRQ0^7NMWv|@x
zwG+T&6#DSD0;1`&kBdyQ56LC)MX~>1olS!p$pSkJiQ^PTspwbpG9e!D!m!-zBA%$k
kZ}gYfNaCF}xV$|1>H6z0+kD
+ * @brief The implementation of testing application of the PPM CAPI.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "ppmtester"
+
+#define BUFFER_SIZE 1024
+
+#if !defined(PACKAGE)
+#define PACKAGE "org.example.ppmtester"
+#endif
+
+typedef struct appdata
+{
+ Evas_Object *window;
+ Evas_Object *conform;
+ Evas_Object *navi;
+ Evas_Object *msg_box;
+} appdata_s;
+
+static void win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ ui_app_exit();
+}
+
+/**
+ * @brief Prints massage into the message box.
+ *
+ * @param[in] obj The message box.
+ * @param[in] msg The text message that is written to the message box.
+ * @param[in] ... Additional arguments declared in the text message.
+ */
+void print_msg(Evas_Object *obj, const char* msg, ...)
+{
+ va_list args;
+ va_start(args, msg);
+ char buffer[BUFFER_SIZE];
+ vsnprintf(buffer, BUFFER_SIZE, msg, args);
+ va_end(args);
+
+ Evas_Coord c_y;
+ elm_entry_entry_append(obj, buffer);
+ elm_entry_entry_append(obj, "
");
+ elm_entry_cursor_end_set(obj);
+ elm_entry_cursor_geometry_get(obj, NULL, &c_y, NULL, NULL);
+ elm_scroller_region_show(obj, 0, c_y, 0, 0);
+}
+
+/**
+ * @brief Clears the message box.
+ *
+ * @param[in] data User specific data.
+ * @param[in] btn Pointer to the button object.
+ * @param[in] event_info Additional event information.
+ */
+static void _btn_clear_cb(void *data, Evas_Object *btn, void *event_info)
+{
+ appdata_s *ad = data;
+ elm_entry_entry_set(ad->msg_box, "");
+}
+
+/**
+ * @brief Creates the display object.
+ */
+Evas_Object *_create_new_cd_display(appdata_s *ad, const char *name, void *cb)
+{
+ // Create a scroller
+ Evas_Object *scroller = elm_scroller_add(ad->window);
+ evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+ // Create a new item
+ Elm_Object_Item *item =
+ elm_naviframe_item_push(ad->navi, "PPM Tester", NULL, NULL, scroller, NULL);
+ elm_object_item_part_text_set(item, "subtitle", "Test following privileges:");
+
+ if (cb != NULL)
+ elm_naviframe_item_pop_cb_set(item, (Elm_Naviframe_Item_Pop_Cb) cb, (void *)ad);
+
+ // Create a main box
+ Evas_Object *box = elm_box_add(scroller);
+ elm_object_content_set(scroller, box);
+ elm_box_horizontal_set(box, EINA_FALSE);
+ evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(box);
+
+ Evas_Object *inner_grid = elm_grid_add(box);
+ elm_object_content_set(box, inner_grid);
+ evas_object_size_hint_align_set(inner_grid, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(inner_grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(inner_grid);
+
+ Evas_Object *bbox_scroller = elm_scroller_add(inner_grid);
+ evas_object_size_hint_align_set(bbox_scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(bbox_scroller, EVAS_HINT_EXPAND, 0.0);
+ elm_scroller_policy_set(bbox_scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON);
+ elm_object_style_set(bbox_scroller, "handler");
+ evas_object_show(bbox_scroller);
+
+ // Create a box for adding content
+ Evas_Object *bbox = elm_box_add(bbox_scroller);
+ Evas_Coord padding_between_buttons = 3;
+ elm_box_padding_set(bbox, 0, padding_between_buttons);
+ elm_object_content_set(bbox_scroller, bbox);
+ elm_box_horizontal_set(bbox, EINA_FALSE);
+ evas_object_size_hint_align_set(bbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(bbox, EVAS_HINT_EXPAND, 0.0);
+ evas_object_show(bbox);
+
+ // Create "Clear" button
+ Evas_Object *bt = elm_button_add(box);
+ elm_object_text_set(bt, "Clear");
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+ evas_object_smart_callback_add(bt, "clicked", _btn_clear_cb, ad);
+ evas_object_show(bt);
+
+ // Create a box for entry
+ Evas_Object *ebox = elm_box_add(inner_grid);
+ elm_box_horizontal_set(ebox, EINA_FALSE);
+ evas_object_size_hint_align_set(ebox, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(ebox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(ebox);
+
+ // Create a message box
+ Evas_Object *display_window = elm_entry_add(ebox);
+ evas_object_size_hint_align_set(display_window, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(display_window, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show(display_window);
+
+ elm_entry_editable_set(display_window, EINA_FALSE);
+ elm_entry_scrollable_set(display_window, EINA_TRUE);
+
+ ad->msg_box = display_window;
+ elm_scroller_policy_set(ad->msg_box, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON);
+ elm_box_pack_end(ebox, display_window);
+
+ elm_grid_pack(inner_grid, bbox_scroller, 0, 0, 100, 35);
+ elm_grid_pack(inner_grid, ebox, 0, 35, 100, 65);
+ elm_box_pack_end(box, inner_grid);
+ elm_box_pack_end(box, bt);
+
+ return bbox;
+}
+
+Eina_Bool _pop_cb(void *data, Elm_Object_Item *item)
+{
+ elm_win_lower(((appdata_s *)data)->window);
+ return EINA_FALSE;
+}
+
+/**
+ * @brief Function copied from the Account Manager example.
+ */
+Evas_Object *_new_button(appdata_s *ad, Evas_Object *display, const char *name, void *cb)
+{
+ // Create a button
+ Evas_Object *bt = elm_button_add(display);
+ elm_object_text_set(bt, name);
+ evas_object_smart_callback_add(bt, "clicked", (Evas_Smart_Cb) cb, ad);
+ evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
+ evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_box_pack_end(display, bt);
+ evas_object_show(bt);
+ return bt;
+}
+
+/**
+ * @brief Writes text into dlogutil and into GUI.
+ *
+ * @details In order to read a message using dlogutil,
+ * type in the emulator's terminal: dlogutil ppmtester
+ * The 'ppmtester' flag is set using LOG_TAG constant.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] privilege A privilege that is to be logged.
+ * @param[in] msg A text that is to be written.
+ */
+void log_privilege (appdata_s *ad, const char* privilege, const char* msg)
+{
+ print_msg(ad->msg_box, "----------
Privilege: %s
Message: %s", privilege, msg);
+ dlog_print(DLOG_INFO, LOG_TAG, "----------\nPrivilege: %s\nMessage: %s", privilege, msg);
+}
+
+/**
+ * @brief Based on ppm_popup_response_cb prototype from privacy-privilege-manager.h.
+ *
+ * @param[in] cause A value representing the reason why this callback
+ * has been called.
+ * @param[in] result A result of a response triggered by calling ppm_popup_request().
+ * @param[in] privilege A privilege that has been checked.
+ * @param[in] user_data User specific data.
+ */
+void ppm_popup_response_cb_function (ppm_call_cause_e cause, ppm_request_result_e result, const char *privilege, void *user_data)
+{
+ appdata_s *ad = user_data;
+ switch (cause)
+ {
+ case PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ANSWER:
+ log_privilege(ad, privilege, "Callback was called with a valid answer.");
+ switch (result)
+ {
+ case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER:
+ log_privilege(ad, privilege, "A user granted permission to use a privilege for an indefinite period of time.");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER:
+ log_privilege(ad, privilege, "A user did not grant permission to use a privilege for an indefinite period of time.");
+ ui_app_exit();
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE:
+ log_privilege(ad, privilege, "A user did not grant permission to use a privilege once.");
+ break;
+ default:
+ break;
+ }
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR:
+ log_privilege(ad, privilege, "Callback was called because of an error.");
+ break;
+ default:
+ {
+ char msg[BUFFER_SIZE];
+ snprintf(msg, BUFFER_SIZE, "Unknown cause: %d", cause);
+ log_privilege(ad, privilege, msg);
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Checks the privilege. Writes messages in the bottom part of the main window and
+ * into the shell (in order to read these messages use command: dlogutil ppmtester).
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] privilege A privilege that is to be checked.
+ * @param[in] ret The code of the error.
+ */
+void app_log_errors(appdata_s *ad, const char* privilege, ppm_error_e ret)
+{
+ switch (ret)
+ {
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_IO_ERROR:
+ log_privilege(ad, privilege, "I/O error");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_INVALID_PARAMETER:
+ log_privilege(ad, privilege, "Invalid parameter");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_ALREADY_IN_PROGRESS:
+ log_privilege(ad, privilege, "Operation already in progress");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_OUT_OF_MEMORY:
+ log_privilege(ad, privilege, "Out of memory");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_UNKNOWN:
+ log_privilege(ad, privilege, "Unknown error");
+ break;
+ default:
+ log_privilege(ad, privilege, "Unknown error");
+ break;
+ }
+}
+
+/**
+ * @brief Checks the privilege. Writes messages in the bottom part of the main window and
+ * into the shell (in order to read these messages use command: dlogutil ppmtester).
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] privilege A privilege that is to be checked.
+ */
+void check_privilege (appdata_s *ad, const char* privilege)
+{
+ ppm_check_result_e result;
+
+ int ret = ppm_check_permission(privilege, &result);
+
+ if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) // If there is an error, print log.
+ {
+ app_log_errors(ad, privilege, ret);
+ return;
+ }
+
+ switch (result) // Alow, deny or ask.
+ {
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
+ log_privilege(ad, privilege, "An application has permission to use a privilege.");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
+ log_privilege(ad, privilege, "An application doesn't have permission to use a privilege.");
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
+ {
+ log_privilege(ad, privilege, "A user has to be asked whether to grant permission to use a privilege.");
+ int ret_popup = ppm_request_permission(privilege, ppm_popup_response_cb_function, ad);
+ if (ret_popup != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE)
+ {
+ app_log_errors(ad, privilege, ret_popup);
+ return;
+ }
+ break;
+ }
+ default:
+ {
+ char msg[BUFFER_SIZE];
+ snprintf(msg, BUFFER_SIZE, "Unknown result: %d", result);
+ log_privilege(ad, privilege, msg);
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Callback for 'camera' button.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] obj Display object.
+ */
+void _test_privilege_camera(appdata_s *ad, Evas_Object *obj)
+{
+ check_privilege(ad, "http://tizen.org/privilege/camera");
+}
+
+/**
+ * @brief Callback for 'location' button.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] obj Display object.
+ */
+void _test_privilege_location(appdata_s *ad, Evas_Object *obj)
+{
+ check_privilege(ad, "http://tizen.org/privilege/location");
+}
+
+/**
+ * @brief Callback for 'contact.read' button.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] obj Display object.
+ */
+void _test_privilege_contact_read(appdata_s *ad, Evas_Object *obj)
+{
+ check_privilege(ad, "http://tizen.org/privilege/contact.read");
+}
+
+/**
+ * @brief Callback for 'contact.write' button.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] obj Display object.
+ */
+void _test_privilege_contact_write(appdata_s *ad, Evas_Object *obj)
+{
+ check_privilege(ad, "http://tizen.org/privilege/contact.write");
+}
+
+/**
+ * @brief Creates buttons in the main window.
+ *
+ * @param[in] ad The structure with GUI elements.
+ */
+void create_buttons_in_main_window(appdata_s *ad)
+{
+ Evas_Object *display = _create_new_cd_display(ad, "PPM Tester", _pop_cb);
+
+ _new_button(ad, display, "camera", _test_privilege_camera);
+ _new_button(ad, display, "location", _test_privilege_location);
+ _new_button(ad, display, "contact.read", _test_privilege_contact_read);
+ _new_button(ad, display, "contact.write", _test_privilege_contact_write);
+}
+
+/**
+ * @brief Creates base GUI (window, conformant, naviframe and buttons).
+ *
+ * @param[in] ad The structure with GUI elements.
+ */
+static void create_base_gui(appdata_s *ad)
+{
+ // Setting the window
+ ad->window = elm_win_util_standard_add(PACKAGE, PACKAGE);
+ elm_win_conformant_set(ad->window, EINA_TRUE);
+ elm_win_autodel_set(ad->window, EINA_TRUE);
+ elm_win_indicator_mode_set(ad->window, ELM_WIN_INDICATOR_SHOW);
+ elm_win_indicator_opacity_set(ad->window, ELM_WIN_INDICATOR_OPAQUE);
+ evas_object_smart_callback_add(ad->window, "delete, request", win_delete_request_cb, NULL);
+
+ // Create conformant
+ ad->conform = elm_conformant_add(ad->window);
+ evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(ad->window, ad->conform);
+ evas_object_show(ad->conform);
+
+ // Create a naviframe
+ ad->navi = elm_naviframe_add(ad->conform);
+ evas_object_size_hint_align_set(ad->navi, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_size_hint_weight_set(ad->navi, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+
+ elm_object_content_set(ad->conform, ad->navi);
+ evas_object_show(ad->navi);
+
+ // Fill the list with items
+ create_buttons_in_main_window(ad);
+
+ eext_object_event_callback_add(ad->navi, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
+
+ // Show the window after base gui is set up
+ evas_object_show(ad->window);
+}
+
+static bool app_create(void *data)
+{
+ /*
+ * Hook to take necessary actions before main event loop starts
+ * Initialize UI resources and application's data
+ * If this function returns true, the main loop of application starts
+ * If this function returns false, the application is terminated
+ */
+
+ appdata_s *ad = data;
+
+ create_base_gui(ad);
+
+ return true;
+}
+
+static void app_control(app_control_h app_control, void *data)
+{
+ // Handle the launch request.
+}
+
+static void app_pause(void *data)
+{
+ // Take necessary actions when application becomes invisible.
+}
+
+static void app_resume(void *data)
+{
+ // Take necessary actions when application becomes visible.
+
+ // Checking two example privileges on resume:
+ const char* privileges [] = {"http://tizen.org/privilege/alarm.get", "http://tizen.org/privilege/calendar.read"};
+ for (int i = 0; i < sizeof(privileges)/sizeof(privileges[0]); i++)
+ {
+ check_privilege(data, privileges[i]);
+ }
+}
+
+static void app_terminate(void *data)
+{
+ // Release all resources.
+}
+
+int main(int argc, char *argv[])
+{
+ appdata_s ad = {0,};
+ int ret = 0;
+
+ ui_app_lifecycle_callback_s event_callback = {0,};
+
+ event_callback.create = app_create;
+ event_callback.terminate = app_terminate;
+ event_callback.pause = app_pause;
+ event_callback.resume = app_resume;
+ event_callback.app_control = app_control;
+
+ ret = ui_app_main(argc, argv, &event_callback, &ad);
+ if (ret != APP_ERROR_NONE)
+ {
+ dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
+ }
+
+ return ret;
+}
diff --git a/test/apps/capi/PPMTester/tizen-manifest.xml b/test/apps/capi/PPMTester/tizen-manifest.xml
new file mode 100644
index 0000000..344e47e
--- /dev/null
+++ b/test/apps/capi/PPMTester/tizen-manifest.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ ppmtester.png
+
+
+ http://tizen.org/privilege/calendar.write
+ http://tizen.org/privilege/contact.read
+ http://tizen.org/privilege/contact.write
+ http://tizen.org/privilege/location
+ http://tizen.org/privilege/calendar.read
+ http://tizen.org/privilege/alarm.get
+ http://tizen.org/privilege/alarm.set
+
+
\ No newline at end of file
--
2.7.4