From dd3fd9df3ef9188823d2269763e909f7d203376a Mon Sep 17 00:00:00 2001 From: Haesu Gwon Date: Thu, 29 May 2025 17:36:19 +0900 Subject: [PATCH] [HALACR-50] Remove HDCP API - Remove HDCP API which is moved to HDCP git [Version] 1.0.0 [Issue Type] Remove Change-Id: If1fc2a1aa9eaad64a12589b8a6c1143bb2782d11 --- doc/hal_drm_doc.h | 13 - doc/images/hal_drm_state_diagram.png | Bin 47678 -> 25031 bytes include/hal-drm-interface-1.h | 45 -- include/hal-drm.h | 162 +----- packaging/hal-api-drm.spec | 2 +- src/hal-api-drm.c | 176 ------- tests/drm_hal_test.cpp | 714 --------------------------- 7 files changed, 2 insertions(+), 1110 deletions(-) diff --git a/doc/hal_drm_doc.h b/doc/hal_drm_doc.h index 33317fb..ad7d9e4 100644 --- a/doc/hal_drm_doc.h +++ b/doc/hal_drm_doc.h @@ -39,7 +39,6 @@ * - managing drm sessions. * - device provisioning. * - decrypt DRM content. - * - hdcp * * @subsection HALAPI_HAL_DRM_MODULE_STATE_DIAGRAM State Diagram * @image html hal_drm_state_diagram.png @@ -64,18 +63,6 @@ * NONE * SYNC * - * - * hal_drm_hdcp_open() - * INITIALIZED - * HDCP_OPENED - * SYNC - * - * - * hal_drm_hdcp_close() - * HDCP_OPENED - * INITIALIZED - * SYNC - * * * * For more information on the DRM features and the macros, see HAL DRM programming guides and tutorials. diff --git a/doc/images/hal_drm_state_diagram.png b/doc/images/hal_drm_state_diagram.png index 3f0872494c7fde88b7eda742958b33df66e690e5..712626986e4d85f97a232a1cbb44aabea2fa7651 100644 GIT binary patch literal 25031 zcmeFZXH=70+b;TmD55A!P>~{7DAExSr0c>$M~W0_QJP4Jf`Fk5Yk`dxdW|SmAasxp zO9euUhAIfL0Fi_cB|r=z;moks`+jBYy~o*SjPvjNp&39jpL^c(?(@3x_?r3E1N(&c zK@fDn$ncUC1aX-_5J&&sJ>WM@Z{1&k7mh%ytG`3&5z!^^1DDrDvx^W^o3wxH=5Fva z&s{@@KnOY>&;G}ewD8jdf^Iq)UAk!Vz=b@kFm&CHrSzlgcEF({`665~xyh!xF_%xs z{glj;Ryk*7o3(4VfFca`!0F@j}(RP7cDWGq*K?IM8R^9)9o={RGAXUM^g& z;Q}wuPuX*VmurXQIlxQV-VE?RWW(Mm1j)uovR{t;fB0ClIE~J4 zjqJ*AO*~yL>XX=(7n_$9;2*iUR7xYr6Zjz5IFRxARpF&-mySEaD@o$|{=(E|INo3Q z7e1Ui%($|>Fqnzw-lNA@uBScx!$OZw7uJnD%lzjby zdq3nW2#!E~0N%x%P*bEH-Tv|>o;zgaljds#)pK-j$Ah1@MoDhDyG{Tt-y3~xP889y z3O$#G&>^k?sTM_tjWv@ZydR;-)8!=EOgZU%K=^`vNQ9v^r(8=^pg7@Jplj4NlSUzU zVGu)1K1h^pC=*htfs1Bg!tvP#Uwaco%wC>7@Rj%B)L7hI;U!e$rguH6nAUCQ8nND) z;wsGYD7#{%E3-7y443wb_IM>dI80Y0bn@03%TAt|l$%tTRGK_HsXEz63Kb7BzEJfE zZijaAE=bi;Lih*dtw=-m>_=uSPP#_vKA^99sBWEr4|TCNNuI3ub~B4zH5E5sqt)a- zr$m^&(MoMDsr6gMGLfV_(rm$74cfbsJvUZ$7Fq_9>z7?O&S7Vt3M%CgeuM0v0ZWf9 zwxn;alRWnt##y*ez0GuuMBH8Z)Z+Q*qTNgX>*b~c*)6A3+)p3qty}Zmu;`8ry3Ktf zU^{{~8)Eic8G9vL+iNy;Hvuv9qgY1-VXhiKkScAFLzq!nNM9UNrCzVx^c1+M?w(yb@Kw9 zk6WIhL-X{3_r;Zmi|zJ7Tk$ZS?gHbNXA)kjO{+-%-b(eFOGd|y*Wqg2`f~97cjL77 zA~oiC-e*1KIG95?fi)<2sw0jtUu~Zka_&oR;__Q{#0ai3Fw*kryxpC^tEcXH&%0ao z-+zOBAFUQ+`_V*#s_EXCv}TCOrMB0q%Sg)G6_o1OEpcSr)aNOgZyBUEznYVA_*3@b z$oy%H#VRA_474oU!ykP-MUj=QTF7-7SLX1Jzpa=NX}fer*I>0RyP0E(SATnp+Eed^ zouipz?&k8A4pL{h$ZY3W&YX%xPaEr64_0QmZARmIgw4i{=CA=%K*00$&XG zf(0ac4s8E4Qgb)%NB^~)``29?`V4uV6dg+KHSN?+5Q)Andoc}IzDD3n`Ip>IP1sL{ zLVu+~)tV`gy$1N?xqe4nrD#g;rA1DM`(MY0b|+u=Q<=OV%pY^AyTmB^^u;s~Ce`WV zDytpyD4soDt2f?+K=zX0lSldkav^^&>`+t@YFll%>*U~%k}oM@GSJMKig}&L zt=AYVvf88k8#)|rXxy1ICynt+)wt1nEZPGE9{U&&5yf;K{CJ+-ploonRd&O`3K5tS zcS-ng2A(U}IY!hWyOitNQHQznsUJK?O6U79nH(?|a7KY=dQxl#>WBR8iaV4%Od~Ux z!+DZI#xMK!c1NXY=BxZ6O`n%Wh2yf5Hj3x5G1AbG0XU=RwIB9s=aDOm*;~pLv+n1F zp}4_MrnHq=pVbct>dhVjC=N)KbxNSlvwSv?FcM_j>Q!8K*wX=Xu~-z=f~+o~8LfV- z>{i8Ekv=MR*s0vCTzJA!#*+b=7SZ~d3>qKWsRcK59Cy98Aj8VY;+kaois|wusk+O& z^GI}%VP|fO1^;}3*DW&dItE8t>NwSXAR5L~GwIU);Df2``6iknPon#gJw1n_hf|CH z6woo!%ijw1#irs&^K>d970v}ifeaWXIa_Is7}4?j8j(PSYdfJPP!qB7Y?3 zhp$kv`tSjfH)lD5pMqVe@_%};_3LMun8dos?*=~5BSff#lrn1WkPC74#bdt<=k*7 zXVm%$4p_d`io^v}VS)34b$;FSjktA*Db8+BU>xdJy^l%-F@NqC)RM~yl1(Lg_`W{k z3!OLiNKCD;t3H?`s$NmEXZ6YSGAI!MFxwhnaK1py7L;`D9n#m%{mm@$a zlb_y$w32BLB$%sCh(N*4QX#{lPF^EL zk3~mhq~G6+D=pC(9^{5>uhwwcmz!Rj)c7Rzt;x)t8`@s~`tE5-__C~qi7}lhxvTpQ zSU~RQ>cU_)yjP`sHeJpxXW#_%o(xQaU3}$h3i%GqRLXL9uYxz4tb>xr(`v#Yy_L(z zioOeq6XI8E2_{eXD0OYAeB_M2%zjfKaO&7^eMupg0j8mR2QhDyd;4i@X8Q{>q9=`Wkdm!JE zz9jJwMH1>u15jIT_`Ya$;1wkx>PKGdF*eq42~35$7jw@&Q?FQnew+kElg#_k+0j9*KTU9cnxanZDxm=Hxips`|vwp9l!TGh)KbY-pfglv=HQMp?|dYBL* zg)|sXq^etRvgDM^rz__3w1NiysP3M#vX0gb`PQ3YaO7oC7;VLjwXdNOm083keYEx& z%!u=db5BZVS~o_Y^)m_6%sY8Rp3bC1bzOt5)NmzEfQCWufqCa9u>#}DvGFvAbGa6T z(DJ3rR(4O&E*)BQx%b79F2M`?m~MBd*tW0FD}L|M}_7*`*1|wXp@Qp2Kn|u zjO5+5R+ksY5_c`1KDT?y%?n$gYa^ru!c9+G2t_Jtck39|G{1L`<{j!D6P0K zJAz%id}itAx4zUa&QY*x%>MN#thQI5P67*k!6@#_Gaeg>=Qvhkp{@ZDX0*|AuyaT| z31lAMICMd&TNsMNSG$LQ%34s->AVe3YdC#%Ua4DtJunq!a9qOh^UVTH?OydwstB2G z#Q!>*(A*ZIXb__pR3kCdoGFgQ_wma=98S5}vQEvKD}xx9YPdG8^@>d%d0r%_k?7wz2YOt0FeKy+D@&xa$opVaCaw8lvCw2p17 zt4E)-=ggJtFeiCgDcP`7ez(}bC3Mh&G&K`?Gln(iIU`|jNgFbR+@76HU~TBgxb0G{ zA2SHs49&d1+vEk4;_X_)3p*GbtW$tkCyp0B!S;zqRes%ddJJnZ z%Q!_1H)S}Yz)D(YR4JEUjW&d34(+>dx)^ii!V(J!*-6r6qr?|oHyg+jjScZFP zqVUXGU!NRp7#XD`JFuhXzO`#o%HigZP#2_AdFq3BGaowe7T z=30Y%Rt2MHrR+JwN_1T@vuz>LQ5T@SvutRZ(#39_Y81f^3ME;apL^cNzb^tk+Ed1 z+b^STpKv=wKGCNZ(SuyGD$l$wrgEqXSW5v&17e|y*nDjb`u=Wz0r`izfr~@g2I&Rz z2ln#X>FYc9Aj?F48Z0g!oBr;4^)Bo-CA|}7)DSB^I%3B@83K8xIlf?U=q6_kA3HX< zOEFq;RCbtUaq?Q~>yHX=lfRsg2n^=+Tg$|*Mfd|L`WvF(C4)u6UJd2+d8EKFQ(U|R zI>$!Jr-K`&wq50NI$a>d0E7K)ovK<S6FK5rc&fi+UxI8rv!!#6}Fo>1>;PTFEddD0QAiHE5U`HMcNJ~X= zO!?i}U*l!^W8c$q6bkGrjAxeDXh}uQ-pV4Y6%E6vxy49YDplkaNI3@<%Ja)RjMJkd zCJR0X*;16Foxw0Btfb@q4^ZmfG%>FPwE@H2Fm2QJv+bi#cCpTZfL0nA8Mnt| z`eO7(uz?7Z3^QPbW%GxZcSTLt6lO^S9o05vUOx)_B9J&%Zi$ubMgu3&O~ZV&35V&e z*Q=_5xBST1$U6=`{jnq*O{u5e=63T`plZWwiaII-jwc^tI~Ay246yFDW7L?xZ7_bC znsF?O_suwVBnuqZHPhVZjR%X?&TWz&Tcu_QEmzX2;pSr`ABkR`1u&zS(?PIPJ*l-l$c=V!BkCU0>4(T7hrsm1PxpYZbDRu;*_~*@&~@C( z^#ICT2Rrq|0)c8(y+%Y|?e*woxJEI9R_&gfFo%W&fUjmdMq$~}{lwL#D(S@h;@OwQ zMTK(9@~7?jgOr*#btHhzYsl5`R%=VtQ&%4V= z>)zM5J?zmH3VO1s=>W`>yl4BxfnQw5aMq{sqbn`Q?U615MJTcUk;fjBQw--QS0q^U z>HuTN#7bYhTu=wG>b}Yo%>>208kqitl_AqW$?we}08QOox)};&ME+MxJ z49LX5Wa0t4C>`DU^(~1T^wFEoc`aHZ2_yNKQs_2Va1VW{6qRG-GLv3aRNc8baNY}= zI>8RnV{?U|TGoF64u3usx(_B;dj?fv!3Rl|4;HGfbIL;9A3}eAebZLVEVq0!I zyE8R{O2B)s$iQE<#x2a_*|F@$pi-Bq-T|o6WRaf%rUcr9-z9V}a>RkhFCtweK$u^t zeCA>Fmw4o_ohNM%gN_Fzpm3B&I_Jq8ICJj-6tQoTD zujTB}_d%;=)iU@#Kl~tcOlrYX3T~!cR1t2rxjLv+b$?fl1h5-pcQkUy0e3yy#MndW zqJXX$1ZzEc5t-HuGFrYbN4E+v47v61A6|NXx^K6jD5GnJ6IcL^L8<~2ts;$S_@Ztk z<66J(AT$VeU+J`{n%!7*(b&q!NcV^F%9FX?yhV>iI5m_-#H zU)T5Z^;kXa*HPP@m?daxKToJm_^%(IL4}mRaLXwB5)-r$8Jv6U+2aE;KUWJF{|tT6 zG~#*nsU0!uUIQ%`rNJFq7J-`bK~gT3etd$bdlQIzRSJ#+SxPzZ)Kt;4$r0XdedgMz zy9qSq0vZ|kA}Qybw-0VjdCy&6o@)=bYf^FX<0bbsex z>;I#w-nP+b6PPpKj%@+o!c0J-U`z))EeWl@;nU|0-IdvGEStqP6yF2TRcX2DaOV0X zH!x?4d^7PrsDV7iszWGqW=(rw0$^(*N`dLTLNodILAvy`nzFIsfH~t-RTeDp^9x2Y zSQWv{g;fsqOt7PKb^9)a=H_XKpzBvZnrGuBDtOx?nW11DQ=^luFSjt1?2>HcAgteE zs1gMv2B~|>7!k{EZag*Lq4#-f7sur6^K04_jgW+*7#n0y{t5JINxsTqX@h{Z2V7I2 ztnRiQoJRo16Vox3mT@lXqA!XB=0VDaaj~9{%tGaZ)8)u%t7lSM^}>I>mzakfjlna7 zgh~RpSKDMp{OWzPw-(bxWt`^mQ%~K6*Yh=pTP8dZ?EbNEc zK%kwHD;Jgim7-~`0(|Y%r*tdL&bwd!>Zx*U&M6i<@R4ImG5ecrU=n)*W)`U@^`M|Y zN=8Fv%=(8YOdmWjOzsGQORvtjC#(61kw?F|>}+{Bp$(dnmpqT$3LSc%QjcEk+7-XL#wDJQ*5|sZU-|14f<|~Jtbf-*4mHz%i*Ti+-D;kCRI8Y{Z*(n_3TgCWoX+n zG{IelHkhfTaWMfM-k>BIWe!HBTJ&H}1u|Abd=Gn)0ahpu&Cz83ezIRE zaC?g$IQ!Sb{LFAgy7S_`77!Iv`GOac46L-zTbWd+q5Y6Z0_O!_sjz6PLNOxnH@ycx zK3`Nls`my?G^S_S#8HYkQU|>f`w~)Jpld|+(9L{vl-}%pGYi2Wg9p)O zY2h+->(%nLEXSfgL#x$cDgi4Ft`0T0*M<&*+N3m0`|g(Tp<{Q2)kMJ$b5IRuW|tnOdlnEg&H`I;5RxosU!k zbL~zI`a-)&UC6Mtih{>pKIji{(E}Bq>M%yU%)Y5EupPG>&w0(ADu|FC=+>7X+sDyV8u;S{2$v!tzxj z^#|b-7t+QF4e z7|!lUkZO)Sw|Sv)agytC`KQTr=4GqJ-Tl8&TtU9Zoi=f}%CHzB8etsZ%bxbLTv!SL2d8^ZfPNYj2Fe$lYv*hnq*R?p1U?%+ zKYifO%hE`{(s0+%=J{dY)-RSCJ2!9WNMh>ij2$dl9fm*3W(VJHNkWVrI|_amnp-3nYMa=HpU1nW?Ny4-G`n$;;(Y!Z%rz9a%2bEfm|T;DKUEDGXi}SgZnA>^ z)YpO<_4xua>TpECLNGP2O6xZ(tI)^uwAFC0e&d2#uFFk`;z|_@Ov9W+V}O{aOo!=^ zD`yRgZNkT_YUjAKGmCU(+=USivtM5(>4ioWOr+q-Ox={aP`#eQ`QG6Z7mpZ3*~jAq zB(PWFN8nw{0f z1=}v8@8VT%xYa?y8Dic)WY8#GQEmk{cY$OO9(6G3)B?={-1UP{{3lJ<78gCFC-ptG z`8`iv(N#04cZY9()R+96g18VMF7Z8uaq7*r0F?Xh-*CGmXqKFZT1s12nuCfzO(Hr~ zbfg(s%;8Qxo}W?iFlAA|Y6%i$|Ny9vSsO~5JxW-N?a(ux}6 zNcZ-(eJ*)mN$oumW^(-Qq5BRUdH4Xd$@A0YT-r!=&Ch2Q%t)H)guXv8;=LKJ@;#7+YbFbWr5y*BtnQC5guWjX|{-Cks533lZAV^B)je0=4 zk&wEjFaz<@IR+ZF8gbweHZ>W%F{gvtAh%ZhpV03EueY{$Dz5DH!72Hax6UB*E`PL>ztVOAlzL>kHhhZXH z9t3Qsx#$cM%inCKlMX_oXC$FL*J|fng^s4Q*y0RF!Vh_?WojxDzntNzQb_I!$uvPU$bqaYTEk@k6`H?CW_w^pe0#VVAOz$Jd!6 z5e@%#__9~zQ+}?j4CACMhb7RwAfl9%kgK}Rc-PWpi^<3dnZE0ZXZsuznIrky6zq-~ zC10nc@x<&Dw zXp2_Dp32uX5=7LU5lzrkBqOb~BB|OgqSIQ#i`nql{%8+UhRbAQGM1a~U?i;#e~$1I z3+DOru1UT6+jJ}q`+*X*&4^`>|5Lka{1-lQ!Wd-h0<>PI%R2q2yryt2P6}5t6&WLG zy*FdI8d>i5SK~IxbvyL7>qLZeYDxz6=SMHp@vW|H+IG(Na1;SglXqHJY8YS9z!IIT9l|SW6a~VP64wwz*$;YRILPLfG;j0oi=D zE66hwOO6dV@Spdy+axg#hKX;GSv>t8D-1g?PSePz*jE;v+XY=rGCVbknWXhbml)Wf zxbT4EKj{N}zPF^|af1xYEqCTH*p9E;qP+cIbt+Bn?hD$;o}h9R#qWXM(d&sv{+sN# z1r*G4zv^?DluY#wIrMg`s5D(FFgdKVtzBi})H;%mH~J%VQX#;cV@m$t+Gk6v{^2Wl znn8{G6ThK64_^7xZWWZ5oxigzqBchv*piAbigJBC-5WEdI?fT{9Ym^veSliSWJqF$C)2XqYF|M>Zry}^VYg0S%h0C!8o$;VgMd)wkNo~#= zmBU(1d2cr0<58$aKUNeYXK@>Q2Ml;jIvQDX=#5@W8S=A}jPoUm_zVi>9CO`RtqWcV(i9J1eQ%}-H3PcoDh(z)+^;8x+g z#iWqC1f8P>o7Q)IN)OO!ETsJ&)^^=-O-Jgp+I*yFfcTY;VOiCt%PM7?(|i&B&1RZ< zP!k>;PmpuP7>BK;xP@+6wW7V1o<@;>#Mt^zwbi)1Qc(+{rDas7b3EEiyGbpY6b0Yb zE%BR~4DOF?iiH^vtDI-524BrwY7A|2@ctfn)>EHIQR*u+ySL`|q;Zc)KsWi!Qe_(U z;D<&(S7KXviO26GWl*$93OLL^^c9Ea5A1Sm*j88Q$E6R1BJUxni!w1 z)x*~ltDXC7Coj&F>usR@N_RW7TG7$9efE?$T9q%&4%741h$PCAi6%TkSE@m#smrW( z0%k;~IQW6zq|Ni`_0BTS4hoz=JzVM^boH*cPN zrJCxk0k_o4O!KjPk%2iwB;ktZnnvuWXUyA5$Y+>Yum5airBKZB&urUH zHntHj(kTwp>p7jF@9W&VNLs;G8|MgxdL?<)tv9p$hy{>l*Jwjh723q3%^|3EqbVq& zy~A%3fz@kDy7xVpG`7wd^cT3yD8Q;~vNmrJ@|yK01r3KZtGWU+Hp3caSoLI}iHW1~ zGBSd7BWW{4fwZv@fh&5Mcw*bJ^#i$Ta=7u%i<|ys9^Mo;f8^#xzd?NK2sMkl?$dh% zcz@^&GGMj@gFx#$3ZANutnYAENes%;aI0v}4jP^o@{5FLY}Qu{Ox1OHwyaUv&6c;m=j=k~Laqjcg8Y1bdfNziFMmMBcc9Z}is}sUOK#f49*rGa)9Qz5bgZ zIX=MfH}^6vx2&MiCU|nE$Q_}8!1Ob>@T~DVXACUf-!V$vduVuSPJOb%VzNWoy>0XL z#Co?pverY~%j3?6&XI_|>rvaURGLEDPEHn^M3}bS&P+N0!!KJG%w6Yp1aSbb(QwFF zBM#{~{w?W+-W+SVko+t!wpDSg*^d!|jO#qMJl#~Cf=5Rsenhjjv|L=8XhGNgUTjd- z@}Hg}Joir&sE?PVG!2 zc+3vea?~(4WGwJ+HyTE4IuO6+I6x8^bh)w92(B$)&@m9)j+;ME2)r*n6eR}pmv|JC*5d)=gMj+|+ zwRK9u(vsy^%Dc0C^HYje>rDo#gtBIlP_v}3T0=lSO+oVK50&49H(PF_stbwDXQ&0= zJlqp=D@8^Ac2cv-B)%%2M$$Rzgk{{F?YZ{_VvVgFdZfI@C?C_=@(%L*;5Y4r`c4<4 z3ft|8SHL*CC#HOy_3cK{)b|XX0Rpl?MjfaU*VfVbc+)?*>7>SI`Nuf~&IK+nM!0J} zB3;dlu_v2$i*KCOfe5`e#JG^C+eP(vgf|mSBMx1?C+2m0@;&x4BmBU1eK?SAvpqpq zaOU~HpWU+lax&%VVn%qhm88t%5tpR0|OL_I}R8$@i=n7wN22$3+w48P)# zu!uUgzC&jmq-73$XssBZ`j@89Q4Tn0Kj97-YFZCAz!F-k4Mg7|@`9WU^aaV(b2iNO z;jly!d*8mX0ltuLSH!?5Nu{&eWz-g~UEzy08QiRQ!&OGynet@#JJJQ~PO=_awkqtIab?%A50plz5p=Lt)2>j4p~sNjY|A zDzMg9u49IjIvx_sK1MAg=M>Vj>Yjm{$1RSb@=KU42&Ii{1~i|H&0eB5 zejT3B!9$pBn)CloccKM7dU-yn9+WhM7ZIItuTaeh?7fJ&-h!uo*Afr>Q_S?z#(k!V zex>Q;a@Wbg+_bct@*nk-&ei+H!AcWT1oMOPZ%*j_W9P!HuJyc{UbX+LE!`998uc1t z+5iv%qr{|xTp4!rJK@$G)f&GY(RJ2r=dm7+OS3Mh%1)7@s=454qgNL0^n}h9&E-j1a8|9&UyUdYutmB92Nl?L=U zdUD9|s?eS9k;5t!u4=bLzd65|nFH5RnP+E)-R2@H4|oeGd<)rp)`B8NWC!8z|Ho-W z61SfJx6?SM{s#O#7)j)L5f>R1v6@=qjXyzkSuV`@8Rj+;!gPH4FLMvy5&QIi5qp0+ z!t;2NM|huWzAQ*Q;t1v!CQhU9^PjlfvZ#e5w93 zb0F{LWfmUQRC<@p@EMX-p}xY-R5Emk5ki}yM}Vy-y0Oprc-(ZO`a9s0g+ezoLub$; zCHb0s&LV9t&6?gh8wcv1aFHOXbc;FZ1b=BoxptS1K#8fdM?s7|4s@%Cu9a-0mj$g z0?k&is%qD9XZ>D;{<0VTK4^<-?)0h-SM**!JNZv6$+%bjOgHhxNJ!k=Ohp}tgL?0G z45Nv3saffBvOsoxscuO?4x%&4GN`$ub})Th!xPu~Z>zX^?>I5A1x-Cqdi_rxX}xQ4 z;htE~J8A4RTIOH+O$SxfNSfNEHnfTlY8pkZ;8u7w`(DgZ`W4m=SK0dIRG&JfiA;{m zA!sSxa`t<{Ztf`hnd)EbNY(3|Yr0_zfkyQ!xr+aeCzNz&AM46B|7z7||A-ss?b>}( z*Mz93D`_^$VzKLs=@0ZmKI1kKhyN;YfawCQN!Lvzw38TiX7`wV(88%dhZX--1V#KK zYmt{x*u6Lhh8n!X^AOqPyFnBc&`?N)WKdol5d0@t+c31Mr`a_R^(_2bWX@*$x^CEd zB(Lt=i@D&54&}AL4|*CAD5c=4ofIcVm@xCVXzk{EpQ@r2E)HL>8R>Ug`$^mPYsr4l94D-JTyHS(skT5)^V0_}%?fmsK z#E0ZPAsda95K?bMgl|3Z=2Ov`_L-(;kymJuq>uhCBwvAX+5_DCXd}*8`f_EUE3gS> z8SSPiQhimh6B=RYChU3r_i^JA_viSZh2RfRC*|Qj@jTS6WZqf;+>r8ZE9`@;yV(eJ97=v(r93 zbKpP6zt*2w2@AycLbIQg zKy^Aky-fA#KN~zS8We~%ZfOa;Ns7t^!ThAgSl!r%rIRv*6T3hBN9qJF`ma=Ew>GOk znpi&Pf7_;`Om(y{waqU#ApD5w5_G1TroGjKW~a;A%f)X@ zYCQ>sRaL|r*}cNo@acN}+mbq6+?pKYt~Wn^@+r5xZvw9=w-BjF9`x>AzRH~aPkvfK z4$Hj-a(%u7Z-?d6(3wsVDM5+Z`$Ruv05TOZZdqQKeTflh059{%33fu95B%0dTRQWf zV@u*!oe?c`ALaweiOa^hzsqol zT3t4m$Ck?+NldGd&jl=x=`pLXwzt5(-$uc5!aFp3C|Bz_yJBm3 zI{AALa{;03k~T8)!%Y?eX6eRfaGhw@$|ib@SJ-Kf0tU{W zVgS-P4&d^4mSpfV>tW7IfPj$Smu!=GuFrYo;>cA^4K^5u5tu>ceu^yJ_5SMLw^NZO zrv)D_}uM0wRgoAEfnWX1|$O9 z41@KFpq1u>B&CwlNa>^vfK*!4S`1xmWr1OSj+4iRQA<1o6aL%rXD9&P93L9U<~?}p zOmZYCb^dzc?TgY3Eb)$xTKjO7Qr*$e_P;0R`c?;!IsUa+u1vy&n#-u;=XmkR+rmvk zO#w@|;#dF)&^Yi}K-#>$D-zkTd>_!S7WD?18*~Cn<6_3A_!jX%*No3k#N=~}o%H{G zx3;+j$P8xRRNz0w0hszOz^=uzF$f9o*_XK;dQFnF{4D(6|l5qWMy5ln!E=|Z6-32HR`3Oh6pWco4< zItD9v(x`zEADGYchLzsS(vs#TbjZGNIP|gLnvSP`nVlMgkJo` zHSUhYIL8w}NMq0)9D=={1jO5|p zVgtZs_CQfyw%jQLbsS9I1narYrDGre$u;P?Bn=;ekC^1zNA*o>37pV%xLeT2>pD=M zLQo4VlQ7H!yj}o6zo1{tRnv_7a~pushT9KCbeP83RF3YIxfqLzVj)(mXQTn?H@s*t zDuypx`5b(7k}jp&l^&SwA~RX-3Xi!VxffX=*AiUg7l2=6A00yzYZnvFbGuTz4B4*K zl`WbxW!!(}`-igaq}Sp=Q-64;y6nPPD|OyFX}wY zi*#}*TF^)+G>bBl{9^tohEF}B%;{sujurfXd$5qL9M@DsR2AJFEbxre|i}4%4hI$tT0uyK`YJ zHLxWa4oaXj8#jhSo`nI|Z?9B1LwNs$q

-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 literal 47678 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, batch_command, error_command); } - -int hal_drm_hdcp_open(void *drm_handle, hal_drm_hdcp_device_type_e type, hal_drm_hdcp_protocol_version_e version) -{ - int ret = 0; - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_open, HAL_DRM_ERROR_NOT_IMPLEMENTED); - - if (type < HAL_DRM_HDCP_DEVICE_RECEIVER || type > HAL_DRM_HDCP_DEVICE_TRANSMIT_MULTISINK) - return HAL_DRM_ERROR_INVALID_PARAMETER; - - if (version < HAL_DRM_HDCP_VERSION_2_0 || version > HAL_DRM_HDCP_VERSION_2_2) - return HAL_DRM_ERROR_INVALID_PARAMETER; - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_INITIALIZED); - - ret = handle->funcs->hdcp_open(handle->backend, type, version); - if (ret == HAL_DRM_ERROR_NONE) - __hal_drm_set_state(handle, HAL_DRM_STATE_HDCP_OPENED); - - return ret; -} - -int hal_drm_hdcp_close(void *drm_handle) -{ - int ret = 0; - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_close, HAL_DRM_ERROR_NOT_IMPLEMENTED); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - ret = handle->funcs->hdcp_close(handle->backend); - if (ret == HAL_DRM_ERROR_NONE) - __hal_drm_set_state(handle, HAL_DRM_STATE_INITIALIZED); - - return ret; -} - -int hal_drm_hdcp_start_receiver(void *drm_handle, uint32_t socket_port, uint32_t *hdcp_id) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_start_receiver, HAL_DRM_ERROR_NOT_IMPLEMENTED); - HAL_DRM_RETURN_IF_NULL(hdcp_id, HAL_DRM_ERROR_INVALID_PARAMETER); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_start_receiver(handle->backend, socket_port, hdcp_id); -} - -int hal_drm_hdcp_stop_receiver(void *drm_handle, uint32_t hdcp_id) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_stop_receiver, HAL_DRM_ERROR_NOT_IMPLEMENTED); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_stop_receiver(handle->backend, hdcp_id); -} - -int hal_drm_hdcp_start_transmitter(void *drm_handle, const char *socket_ip, uint32_t socket_port, uint32_t *hdcp_id) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_start_transmitter, HAL_DRM_ERROR_NOT_IMPLEMENTED); - HAL_DRM_RETURN_IF_NULL(socket_ip, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(hdcp_id, HAL_DRM_ERROR_INVALID_PARAMETER); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_start_transmitter(handle->backend, socket_ip, socket_port, hdcp_id); -} - -int hal_drm_hdcp_stop_transmitter(void *drm_handle, uint32_t hdcp_id) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_stop_transmitter, HAL_DRM_ERROR_NOT_IMPLEMENTED); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_stop_transmitter(handle->backend, hdcp_id); -} - -int hal_drm_hdcp_allocate_output_buffer(void *drm_handle, uint32_t size, bool is_secure, hal_drm_buffer_s *buffer) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_stop_transmitter, HAL_DRM_ERROR_NOT_IMPLEMENTED); - HAL_DRM_RETURN_IF_NULL(buffer, HAL_DRM_ERROR_INVALID_PARAMETER); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_allocate_output_buffer(handle->backend, size, is_secure, buffer); -} - -int hal_drm_hdcp_release_output_buffer(void *drm_handle, hal_drm_buffer_s *buffer) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_stop_transmitter, HAL_DRM_ERROR_NOT_IMPLEMENTED); - HAL_DRM_RETURN_IF_NULL(buffer, HAL_DRM_ERROR_INVALID_PARAMETER); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_release_output_buffer(handle->backend, buffer); -} - -int hal_drm_hdcp_decrypt(void *drm_handle, hal_drm_buffer_s *input, void *decrypt_info, hal_drm_buffer_s *output) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_decrypt, HAL_DRM_ERROR_NOT_IMPLEMENTED); - HAL_DRM_RETURN_IF_NULL(input, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(output, HAL_DRM_ERROR_INVALID_PARAMETER); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_decrypt(handle->backend, input, decrypt_info, output); -} - -int hal_drm_hdcp_encrypt(void *drm_handle, hal_drm_buffer_s *input, uint32_t hdcp_id, void *encrypt_info, hal_drm_buffer_s *output) -{ - hal_drm_s *handle = (hal_drm_s *)drm_handle; - - HAL_DRM_RETURN_IF_NULL(handle, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(handle->funcs->hdcp_encrypt, HAL_DRM_ERROR_NOT_IMPLEMENTED); - HAL_DRM_RETURN_IF_NULL(input, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(encrypt_info, HAL_DRM_ERROR_INVALID_PARAMETER); - HAL_DRM_RETURN_IF_NULL(output, HAL_DRM_ERROR_INVALID_PARAMETER); - - AUTOCLEAN_LOCKER(&handle->lock); - - HAL_DRM_CHECK_STATE(handle->state, HAL_DRM_STATE_HDCP_OPENED); - - return handle->funcs->hdcp_encrypt(handle->backend, input, hdcp_id, encrypt_info, output); -} diff --git a/tests/drm_hal_test.cpp b/tests/drm_hal_test.cpp index 3148f9c..0cc1f0a 100644 --- a/tests/drm_hal_test.cpp +++ b/tests/drm_hal_test.cpp @@ -26,8 +26,6 @@ static int gRet; static void *gHalHandle; -static const char *gSocketIp = "192.168.0.1"; -static int gPortIp = 100; /* * main class @@ -161,14 +159,8 @@ TEST_F(DrmHalTest, DrmSetBatchCommandP) batch_command.custom.name = "custom_command_name"; batch_command.custom.value = (void*)10; - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - gRet = hal_drm_set_batch_command(gHalHandle, &batch_command, nullptr); ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); } /** @@ -191,717 +183,11 @@ TEST_F(DrmHalTest, DrmSetBatchCommandN) batch_command.custom.name = "custom_command_name"; batch_command.custom.value = (void*)10; - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - gRet = hal_drm_set_batch_command(nullptr, &batch_command, nullptr); ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); gRet = hal_drm_set_batch_command(gHalHandle, nullptr, nullptr); ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpOpenP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Open HDCP - * @apicovered hal_drm_hdcp_open - * @passcase when hal_drm_hdcp_open returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_open does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpOpenP) -{ - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpCloseP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Close HDCP - * @apicovered hal_drm_hdcp_close - * @passcase when hal_drm_hdcp_close returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_close does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpCloseP) -{ - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpCloseN - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Close HDCP - * @apicovered hal_drm_hdcp_close - * @passcase when hal_drm_hdcp_open is not called and hal_drm_hdcp_close returns HAL_DRM_ERROR_INVALID_STATE - * @failcase when hal_drm_hdcp_close does not return HAL_DRM_ERROR_INVALID_STATE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpCloseN1) -{ - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_STATE); -} - -/** - * @testcase HdcpCloseN - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Close HDCP - * @apicovered hal_drm_hdcp_close - * @passcase when hal_drm_hdcp_close returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_close does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpCloseN2) -{ - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(nullptr); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); -} - -/** - * @testcase HdcpStartReceiverP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Start HDCP receiver - * @apicovered hal_drm_hdcp_start_receiver - * @passcase when hal_drm_hdcp_start_receiver returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_start_receiver does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStartReceiverP) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_receiver(gHalHandle, 100, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStartReceiverN - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Start HDCP receiver - * @apicovered hal_drm_hdcp_start_receiver - * @passcase when hal_drm_hdcp_start_receiver returns HAL_DRM_ERROR_INVALID_STATE - * @failcase when hal_drm_hdcp_start_receiver does not return HAL_DRM_ERROR_INVALID_STATE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStartReceiverN1) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_start_receiver(gHalHandle, 100, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_STATE); -} - -/** - * @testcase HdcpStartReceiverN2 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Start HDCP receiver - * @apicovered hal_drm_hdcp_start_receiver - * @passcase when hal_drm_hdcp_start_receiver returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_start_receiver does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStartReceiverN2) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_receiver(nullptr, 100, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_start_receiver(gHalHandle, 100, nullptr); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStopReceiverP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Stop HDCP receiver - * @apicovered hal_drm_hdcp_stop_receiver - * @passcase when hal_drm_hdcp_stop_receiver returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_stop_receiver does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStopReceiverP) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_receiver(gHalHandle, 100, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_receiver(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStopReceiverN1 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Stop HDCP receiver - * @apicovered hal_drm_hdcp_stop_receiver - * @passcase when hal_drm_hdcp_stop_receiver returns HAL_DRM_ERROR_INVALID_STATE - * @failcase when hal_drm_hdcp_stop_receiver does not return HAL_DRM_ERROR_INVALID_STATE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStopReceiverN1) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_stop_receiver(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_STATE); -} - -/** - * @testcase HdcpStopReceiverN2 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Stop HDCP receiver - * @apicovered hal_drm_hdcp_stop_receiver - * @passcase when hal_drm_hdcp_stop_receiver returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_stop_receiver does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStopReceiverN2) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_receiver(gHalHandle, 100, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_receiver(nullptr, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStartTransmitterP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Start HDCP transmitter - * @apicovered hal_drm_hdcp_start_transmitter - * @passcase when hal_drm_hdcp_start_transmitter returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_start_transmitter does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStartTransmitterP) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStartTransmitterN1 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Start HDCP transmitter - * @apicovered hal_drm_hdcp_start_transmitter - * @passcase when hal_drm_hdcp_start_transmitter returns HAL_DRM_ERROR_INVALID_STATE - * @failcase when hal_drm_hdcp_start_transmitter does not return HAL_DRM_ERROR_INVALID_STATE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStartTransmitterN1) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_STATE); -} - -/** - * @testcase HdcpStartTransmitterN2 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Start HDCP transmitter - * @apicovered hal_drm_hdcp_start_transmitter - * @passcase when hal_drm_hdcp_start_transmitter returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_start_transmitter does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStartTransmitterN2) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(nullptr, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStopTransmitterP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Stop HDCP transmitter - * @apicovered hal_drm_hdcp_stop_transmitter - * @passcase when hal_drm_hdcp_stop_transmitter returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_stop_transmitter does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStopTransmitterP) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpStopTransmitterN1 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Stop HDCP transmitter - * @apicovered hal_drm_hdcp_stop_transmitter - * @passcase when hal_drm_hdcp_stop_transmitter returns HAL_DRM_ERROR_INVALID_STATE - * @failcase when hal_drm_hdcp_stop_transmitter does not return HAL_DRM_ERROR_INVALID_STATE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStopTransmitterN1) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_STATE); -} - -/** - * @testcase HdcpStopTransmitterN2 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Stop HDCP transmitter - * @apicovered hal_drm_hdcp_stop_transmitter - * @passcase when hal_drm_hdcp_stop_transmitter returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_stop_transmitter does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpStopTransmitterN2) -{ - uint32_t hdcp_id = 0; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_transmitter(nullptr, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpAllocateBufferP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Allocate output buffer - * @apicovered hal_drm_hdcp_allocate_output_buffer - * @passcase when hal_drm_hdcp_allocate_output_buffer returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_allocate_output_buffer does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpAllocateBufferP) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s output; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_allocate_output_buffer(gHalHandle, 1000, false, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpAllocateBufferN - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Allocate output buffer - * @apicovered hal_drm_hdcp_allocate_output_buffer - * @passcase when hal_drm_hdcp_allocate_output_buffer returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_allocate_output_buffer does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpAllocateBufferN) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s output; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_allocate_output_buffer(nullptr, 1000, false, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_allocate_output_buffer(gHalHandle, 1000, false, nullptr); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpReleaseBufferP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Release output buffer - * @apicovered hal_drm_hdcp_release_output_buffer - * @passcase when hal_drm_hdcp_release_output_buffer returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_release_output_buffer does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpReleaseBufferP) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s output; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_allocate_output_buffer(gHalHandle, 1000, false, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_release_output_buffer(gHalHandle, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpReleaseBufferN - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Release output buffer - * @apicovered hal_drm_hdcp_release_output_buffer - * @passcase when hal_drm_hdcp_release_output_buffer returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_release_output_buffer does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpReleaseBufferN) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s output; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_allocate_output_buffer(gHalHandle, 1000, false, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_release_output_buffer(nullptr, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_release_output_buffer(gHalHandle, nullptr); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpDecryptP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Decrypt HDCP data - * @apicovered hal_drm_hdcp_decrypt - * @passcase when hal_drm_hdcp_decrypt returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_decrypt does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpDecryptP) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s input, output; - uint32_t decrypt_info; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_allocate_output_buffer(gHalHandle, 1000, false, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - input.size = 100; - gRet = hal_drm_hdcp_decrypt(gHalHandle, &input, (void *)&decrypt_info, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpDecryptN1 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Decrypt HDCP data - * @apicovered hal_drm_hdcp_decrypt - * @passcase when hal_drm_hdcp_decrypt returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_decrypt does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpDecryptN1) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s output; - int decrypt_info; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_decrypt(gHalHandle, nullptr, (void *)&decrypt_info, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpEncryptP - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Positive, Encrypt HDCP data - * @apicovered hal_drm_hdcp_encrypt - * @passcase when hal_drm_hdcp_encrypt returns HAL_DRM_ERROR_NONE - * @failcase when hal_drm_hdcp_encrypt does not return HAL_DRM_ERROR_NONE - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpEncryptP) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s input, output; - uint32_t encrypt_info; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_allocate_output_buffer(gHalHandle, 1000, false, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - input.size = 100; - gRet = hal_drm_hdcp_encrypt(gHalHandle, &input, hdcp_id, (void *)&encrypt_info, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); -} - -/** - * @testcase HdcpEncryptN1 - * @since HAL_MODULE_DRM 1.0 - * @author SR(haesu.gwon) - * @reviewer SR(gilbok) - * @type auto - * @description Negative, Encrypt HDCP data - * @apicovered hal_drm_hdcp_encrypt - * @passcase when hal_drm_hdcp_encrypt returns HAL_DRM_ERROR_INVALID_PARAMETER - * @failcase when hal_drm_hdcp_encrypt does not return HAL_DRM_ERROR_INVALID_PARAMETER - * @precondition None - * @postcondition None - */ -TEST_F(DrmHalTest, HdcpEncryptN1) -{ - uint32_t hdcp_id = 0; - hal_drm_buffer_s input, output; - uint32_t encrypt_info; - input.size = 100; - - gRet = hal_drm_hdcp_open(gHalHandle, HAL_DRM_HDCP_DEVICE_RECEIVER, HAL_DRM_HDCP_VERSION_2_0); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_start_transmitter(gHalHandle, gSocketIp, gPortIp, &hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_encrypt(gHalHandle, nullptr, hdcp_id, (void *)&encrypt_info, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_encrypt(gHalHandle, &input, hdcp_id, nullptr, &output); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_encrypt(gHalHandle, &input, hdcp_id, (void *)&encrypt_info, nullptr); - ASSERT_EQ(gRet, HAL_DRM_ERROR_INVALID_PARAMETER); - - gRet = hal_drm_hdcp_stop_transmitter(gHalHandle, hdcp_id); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); - - gRet = hal_drm_hdcp_close(gHalHandle); - ASSERT_EQ(gRet, HAL_DRM_ERROR_NONE); } int main(int argc, char **argv) -- 2.34.1