From 4948c163663ecc343c97e4c2a2139234f1d3273f Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Tue, 13 Jul 2010 17:00:24 -0700 Subject: [PATCH] Remove prebuilt static library "libthreaded_app.a". Make the "glue library" part of the NDK as an importable module, this has several benefits: - no need to distribute a binary here with no easy way to regenerate it - no need to explicitely list -lthreaded_app in your LOCAL_LDLIBS (this is handled automatically by the module import capability) - allows easier native debugging of what's really happening. Note that the header is renamed + Modify the native-activity sample to use and import the new module + Start documenting usage in the header file. We probably need something better, and will probably put it under development/ndk/docs/ at some point. After this patch, we should be able to get rid of the code under framework/base/native/{include.glue} Change-Id: I6e81d70a225a6ca006beabf6e8b42529e8f371b9 --- .../arch-arm/usr/lib/libthreaded_app.a | Bin 57420 -> 0 bytes ndk/samples/native-activity/jni/Android.mk | 5 +- ndk/samples/native-activity/jni/main.c | 24 +- ndk/samples/native-plasma/jni/Android.mk | 5 +- ndk/samples/native-plasma/jni/plasma.c | 28 +- .../android/native_app_glue/Android.mk | 10 + .../native_app_glue/android_native_app_glue.c | 278 ++++++++++++++++++ .../android_native_app_glue.h} | 63 ++++ 8 files changed, 385 insertions(+), 28 deletions(-) delete mode 100644 ndk/platforms/android-9/arch-arm/usr/lib/libthreaded_app.a create mode 100644 ndk/sources/android/native_app_glue/Android.mk create mode 100644 ndk/sources/android/native_app_glue/android_native_app_glue.c rename ndk/{platforms/android-9/arch-arm/usr/include/android_glue/threaded_app.h => sources/android/native_app_glue/android_native_app_glue.h} (71%) diff --git a/ndk/platforms/android-9/arch-arm/usr/lib/libthreaded_app.a b/ndk/platforms/android-9/arch-arm/usr/lib/libthreaded_app.a deleted file mode 100644 index d3073db8f741f1797723b64c138b4bab75d7292c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57420 zcmeIb33wD$_6J(k-B}0;4Hm1SbO^FT!X~I}kq`((f~+!*hLAKQ5R#Y#1VzD}8BuT> zQJE238O0G?W?TpKuMRV#g4>8A4mj$F%Z#WvGU~|t{mwmAU0rn4|M$K3zW3hu>Pz>p z&ON_-&b{X@RduVnk~^}Zv9fw}R(>pb8#H+M$pt5!JZShyu~>nq{NJ(Ih@mcjZkA

%{5Eog_ZcOXuajYD;gTgVyn)`9#4y@0Qx#c-&NGvvJ`0x=Y$A%RYph$xX3Qih|vJ4wOxL|}7X>Qia@ukJK zZKF75v#s7%Lb9ytDgQRdnodo7Syu>_&2sUgC_%8k%icX;G_nYs*US0T>MfmX)EqnUHBJPuojW5sT}(|Z>sZ@1wBvF?%SU~?4ioABy2-MydKIN;M{%4Q#!4 z3VM!ot%&_HTF)MidUkCqDM??U(HUU&W;YBEK+Z@h_99PVk2|3}blS8?h&?JazYkOX z09Cka6?W6@%-tw?C>O01K7OgBq_<~E7nCV{!fK|3GJ1AF%C{&(xZ5p~lGdRkQl6om z*cPN@MAB;Nnyt|DC}KGG_vB=zjfBzAv}2LdeK%7gk;ze{Y>OZz@9)Bi{DP$#Nz1)9 zAtki>80=1ya*skW!qX2iwTQbjWVavsOn9d37PP|dtPU8Gp;;(kc(&{gqOmh&_ixNL zM|Kx6+fQV7Bx`n->@H=se=57Lw8!q*vfB)o;d5lSqyu)##oJ4$ad@umF6D0gPB_kt z+>7s4-yy*c{S3_zu6{z2pO$1yXLi=jh(Knz_C&O0>+`Mf;yEzidY%=oTg078D_nme zcbcql!&>gtSmARwac7|wZhVM4^Q~~xbKI%2!p(1Rr`8HDVNt9Qt%sNX0q(NL!d)c1 zY$hD#e2Ipzauy;&c20zCmD7uLwL&C?FDwA3O?G(Y^}y)ktmG>0qOU~fbb@rTks{Gc z8RJW&J@PV9-J8K``zw5*=lqV{ZoqLMTsjvinUUY(yIp5QdOLQG;m)1m@RgsU%SQJz zWH%Z+R`erEzc5lHdWh0Z>Lc2X&9mM}+0l0GAl>o+zC(F!qd#M5HoPZN`)Hr`kbZSU zq|VW^;WNDPSoEJzUf1YP*pD_16Dbyb48aKB!L(3bkLUu1;I1Vi^^X1`4bt5=iqt=v zN$~NZS-*8>mm(}o=@*vz7%Oh^h`?kw?>>pc_X7y+WgJ&B8`nUvg18qq@w6= z=zZ%@(M^ojv41{TCQ@m12m9qi3q_h5jUrUxM~pNhdLDJZy;yW-Mz>M-J0txxdJP&p z{OBgp&5hp9x<796RYfyc>L-kc>Szv`PdzEj+GrVD_xEp$)DS%m<1xHF1b!&5Ir47wxj3J&>vnE zag7~qO>yU85!cyK9_Yh=?7~i$cY_^mrl~)T7ID2D?Z?jW=SmSb*irOuEBwM`B5t&! z-8jTv{I!U8+R?8W=a*g*akCwr!?CdIQxUh=(Y@?DyW7)X-c~!hiQ>yAi}+Z}eT`AyyF zJv({|+wyPeY>T`DcJyJ^cV9mdKe3~q(C_}KA|AA(4>9jMi$y$SN7u3Nf4@e=!*+B& z#djYN@mo7On&SJfi?}Kj{S4@M-kVDqQz|eFTN0QLkRs3;+My>B6%A_(b4QGUyT#- z&QP=y$I5>ei?}%y-OWgTbCZZ$LeVYg#o_-xCF0gl^g$N#$Oj@m9CC(GwC#4BpYk3J zIqb>dusvMlCqvH5tVEh!A@Yupb28-&`zn#24LM^O%~tj{k#~li_u0o=+i!{dLdY3K zImb@x3dq|Xa#pbDQM;eWuZ5iZI3u*PXNtThIfK_KPBK z3_EMd&$s_2@||I)hTW(DLmrT~Iqd9UKN@5gh`c528J zxO1w_$r7VH?7T?-BW+HXX#cSD0q4?D_P@p6Yhh4vBKY@S7uh{-fF}a$m=6c1?4mB zWg>5gICn8{)9hc0yfNY|qdeVyM&vsq&e<&g4EtS?H%FXj>2Ic;nFq+*5^?D?K4C^9C4oH5pA*EDDt-vr;_|S`+AXAr8zSgpL+XY zkuOVgzF~Ve*sqJcI?cJ5{jt%udIIv+q&bsVz9#!Pk=La;H?h5%?Lv`nNOP{Iza{qB zBCk(#e#!B<)Ltg?hBW7;Fy!+z|Hd>Ym;HCSy5wn8pA`88)Svvz?Kec;o#q^1`(0swF7j(> zPTYcgrHzYklxI(x(~9HmXZ8S*_og|2V}Jj-JzeDeX-*%;=PG--$nT{&_oP8yW8Wt7 zfi$NJ4?I`f&x!m=nv<0Q`5OCUkq@RhkFmYh+U@!P@(!Ur=zpC(T;#)P&hc#T>+CZ{ z{x;2tFg`cf%SB$5?%dDv|H8gS}<5hh`c`C`Gobm!;Xu*A>H{G`FGh@iM%o0xtjg?9($X} zccwcVIUoPpenaHV=}s=&>puIxB5z4|&S3fOxAXb|^0uZsJ816#yF}!N)17|Izs;@} z`O$P|Fzr8LZxs2-bf-@iXF2~oZEqF%wRGnN*7twxcSPQk?zCe2J#V)g0La^$?sQ@K zcG~?#-kCSBOU)AxtD#Q7L`qy;4UY6m=sqkOyuEJlP z;atrA`-VM4TB1o5&k7 zoc{E`-+o-=jTu(x&+M>QZ$-BZz0TNPlZNliNNaqz!}^!i9y{&16ALfA8T*c0Q|8EO z2QFM4IUR4KV#JZF%BYH&&ixEmyU1?13*}`yU9uq_6ZyA@ZJn;{td45iI~TJk?IT_D zN$%|2$ga^r$z81u_9p0mjUsg97s|*>TwEJN=wKf~%A2mPBd?=79zs$_N&66cVD5vy z?IPKI#LL7BSurS?!1_p3ThWfZsx>N_f+`IO9qgN-8WvQ=L`5F2cTFyqsUr<_oMZBz zDkLT^Ng~1YTv3sCW0I;P+0b7gdfMkzvd=zCDu!c}4A}w8MTUn^)DQ44OR;3C27xfQ^dffQ?f`#gg+%*{C$0 zGm+5A=EZeVa)abxEO@1zP)Uoz;+3MO4PIXxy@u%?PsKCHgi4yBGx9#;5qL@&AatAp zn;^aGk$R;dF%2ZHEM-PAA(-CBE1g7Hp&BA8R)ZJt36b@hOdE`%$tPy|SH^_oZEnni%% zy86;1aU~;2Qdh@9)xlm1S6tr+kmzcRN8mIcAh@pPdL*uc1WD@Zav^bqadjj>qN{s7 z0w?GI!FBa#kHl4!AW2;v6w*U*#kG|HiLN>zxr0ptS6c!E*VRcLiEA)HlDaxeNYB9% zS7rhvx?1HCxKgstRy#W%}bpj;1`q(3Ir6)jeU1dYn!KM|i z{{%_uY7kVNY_13e2y`<`lw2PQC|ws#Lg0!~kf7#ofU1Li2xZ_pl8+?QyE{!h;<32A zl#1m#e9L2Ue2>Mos#Gl3^GuJ)WvrA;^}JG;oIkk2m5NEv zzxG&M_)5icJ@4|EToX&lRL}nrCZ`iFm!)FTa~^aZY_hnDmWt(iF7cRLU`xqV&rQPQ z?83FTR7`sQrN`ouTq>69`F}hn7wb|o)$>1v$;pPxc&V85+zC2!3c$s^R4mu?D38fy zzm!b%yg-DcdMqvzree9Cf9El|fS8i0p5GBBClM|!ree}_Yv{~W!v)7w zEZ6fOkIALTluY$}mM}S|aFH?mL+7Ckn2x9<6^x^cO;(jTO+N^`DELgRXx{{V_;2oxU`sez54-fooIhr-`23Y)wji zqv+WgwxrZwhty88nj0v)d#?PT5V*V>Brs@*;HyI5dT)@xsDW@u2wVUT5*RiRIzZJ) zR)m8D#tnp%guo@@Ac1oV2(yL2HRB+Gkpp3w5V(jOBrtR!+$;pHDhCOS9SDy@WsX%` zDmJ7e(0CUHZ+V2{Vn-3&p8c&y8k>To9Xl7Q4mP7#fxQ&2iao*=M-yCE3p~<&DM;#S zjgZ(5FC0zcfZgU1K0BJ=x_ZSUaTz;M;Ew9*Do6!@c@aguJj08Cl3%@SDQT&7tezvb@if<*vq)09w5=x=N@73(FE6( z1C==g=DK^piW|TYLSldAVtjx^S7&Zc$t~{?_(<;j zFM65(Q|ccSz0Ch9^{3pWdacTIu>cm9W}gPmnt)|Vbh_H=FV8>F^n zg|HMRRHpMTi?PRyP^BZGgUx)WCaF47gq|HSGm;CTlPu{bGIwMq=q88-n&T}Qqt~UL zN>NeZ-56h1HGUCNJIS3HpHB1sO7gPIyi;TJe3S|v9~TwZrFqlFs7RD$D7TxuE+n33 z@lK8*F-u1c&)3j*lDj$qoonD&Wb0t}Ll)lZNq9j4P8HQjQ1Px$l4_Qy3Zdc+pd{6~ zqAG=o_kxmCYeY30D&7`KQr#n}c~J2VQIhHzQ7wjwH;a-~Z;NUfRJ?DLq&h4rwg7J- z85L{kwzz}T4)*Ez=Evw+RaehJgo#jCP59==uvlxCWjfv*Vcm>xehiBNa9JEqnUR&k z+Kz9242!XFS(}7)m$2T)H$R5Ou(&J^tjx%th1I$bR(JtwTsgf$2ZehiDj za#Lg1}1Ly!nbz?8632)s9D2ofBL zl@c}zfj7$xLE<7|Qo_?h;N3GrkdR1(l<;>U@OGLZNHiokN(e*MN$#&1f&@b1qJ$no z;0-rJkT`sZ2*_A+V>Vt`ybWhq5{v|kVL`|i35z%93`-)CU@x6rTx zp`!w}Is@98(f7Gz80TdOM3D+)C}9Tn2P_3)x0BuMWe5b63b4*+1~VpSNQS$-41w5E zfeiOCgBhNeONPIA83JLZ0vYx)gBhv6#jZJNNylwUQ*pT#5>dNxHdJlz!oesr@`1Vue)O!SO!Q3Q?b;+i^`at=cW#qZKNl4r zH|9;;B-LG_+Js!Z;o6a5Mlp7HsR!NEj8;Pnb4zDbhpxx?p$27Vf^CgWZ#bmznWvP(XiQAnnUA?lMI( zLZ^V2K5QsVg>RfcU$)gIlF{c8>_solz~k?Ixr>|7 zR#)+NB#N|tWP>(luSXl}(n70YEu-)`GCF4z6&1kHyO~HDe<_mq81{(~NX4vcC@&Jd z8$C2*LU+++M$bjaGbS1-JDP<%LK!8?MAtStg;pjRsl63CBMNcy2UJ#NWA}_o?hZkg z%sz2=ZN**t_(|2Z!i~ft=Z#Pnp=wpn-79;hJzE7JEzAgFsN5fbO&wk8E1<@zcA^rY{ z=!QmL!;P}+=ZyCe7%L2Fhyl)?{ZB-^lN|@KBfp@W0>JeGzRgs1g{$kxJ*e2vG9%|g z=w!1FlCdNEIg+oF15W1KMmjm$vLAR=NQTB9sLa=o+HCIl-ED{Ji1U$prx|Hz^p|MGoT4(ZIU@QYS|ewo(T$Amq4!Bf8XKL)e3Ok-6nzKnol|P0iP2SP zqMXxBsY|10Q#ZwwdTR9gY)ECM)H4vApTO7gk(_D6QRAF2I-i}>m7{`*^R8jyB+Ok_ z&R+C3JEsYRP)-cx3g>J??}+5^nSivMv(UfOb2hia%#ibY#3eJQ88bkuoQ;S>R?ctm z-8$zmwAog6H3A%IQ}!}VzlS6%ryj$>&bb%aLODG_4d=Xs%#oapaFCYs41$-QlYxfF z$Qc1`rWND(vA>f8BJx`?eqqZVhTm_oHSO=%nlU8hc0thW@7M!JlM;J@Sy$V2pmNKE z`V1gtlXW$-^6I5KdyM@vYVw*9G<)4O`6%JFb9<~q1KPh}uy4gD?|ugDmz;V-*G@!4 z(}v*3VD_z;-0aad>|54ee0Jfp9kzN(0Y}Tw`4nkAuSWgsF;bZvuzP;V5|6PtT4K!I z>p%Fi=Zm4S*d2ns4_I6&-+Y#DI+d}dEN`P1m13lw3&ntwz^!8i8cUIMEs{*tnwYf* z`@6k_{rz!T>9vCL7VcUj@p%z@RkR@9wlK>-k<^>Nl(e@jMj>0H{8k@M6?TrPZf_(E zL+UliXR4bc)#VZ1>Q#s@`%Q6xkXcPge9m+5CLM6D%{>*J(0-GHc^k9!;mlyM?fBq#FK`*HF}T^XCo<>L*0ImgN9Go zTYWe&+9w-_{gH4zQX7!Z)aYb!_z=>1-pwv`vdx@(B_}6XduSr(*GRqB%Q;kX9*f~? zat@W8;~-nT?q)MR=@qpWiSKwteUe38gQQ%}L-vy#(f2Z2AI|S~e!}5S$j70srl|Si z@Bq?!O2&MfIoqMSRv#Wi>@JC%`AD7V(#cba*!x+v>xIWt4*OH#^#E@h5@&h#KBc{v$?I!B$8puq=D85JiOBLPG}n1X z`_X6=Q@n{+KgMeSXZ*hQm0gfG*JcVg%s$q$(7fp7&1GI59{R~l)1A!FwdYy=UqWAr zZW{p6w)>Z1WJMn_f;AkPkkt>x582jkcz)vUW*T+^VXmU0SnpR94s2#gj;`lNKuII?*4xTR)Cg&bU}j%bS|xi}Ne%8{=LP zTsz4>hp)5{kXstcK*w=Yue9w^qXy&-9&keUIj2wlQ}=GU{d05k_bmA9 zrt z`I9G)O0u#!WKTXcIf=ZDh6m)1$}Js`TXOoSknJ=7D9z_~%UzP3<)IMEl6z@#>J#5% z=r^eitxsv_B^nyscNAQ(A(D%9hihq6QuKc5CMQSYI(4u#iTs>x=MTuw>z6-S%=^Q9 zCGDV{ldE<~%GAT?S4VTdNSV6Nwi)Dt{`qh@dK9;$NdHT7CD*F29n1gCr~#AFVe)gA ztdPCQqk4`SFlSWmz|&HSFbjo(%^zx$T-okSnu;)qyDUmwZMxV7w%H7{0KSs7%!loaZnfYslOi~Gs3|_bC{JWl%JBYz;yxnBYOUUfcbn8$ajUHd zQTN+X?K|;VfzL(w{1hLq6ph7)+t&LsSDjeWb5h$!BE_sxp4O;)b@$2LOD-syUJ5^tsE6V%6OyUo7$oC9jHn{A9a=`mQC{S5SZ4lb;s3V~JBqeTT_~m14j6dWqit3bxxClpLzJOUO&NS7CzJPnSu{Dws}rTn@J5?$4HEA%;=j~?XS+1wzc!n2dv7fgr?!C z{>VR2tkBNAtD0cLj@c)Yle?&Iv6W}tm@d)3n>{DJK=x0pq9t;S95d}B-&Sk|>PD0I zhPSQCcqDY6-93ERKE6xw*hS1?_s-r;G(9a+l9trd+8{6cavOXyw%HeN-D+J%Tke)o zlIgW&Bxd@_{+bNw$BZdX7Ojp-W?Tk*c(5>9Y#|Q*JzI{W(NMH{Q%tZUfKs`j4uZjyR6RM8E!f^}DsVoc7hrhSl(t>z_uCj9*%NnOiC-xD2c>a#^puU4fO4n zbF{|DE$6Q@wjEW@p7B_*EpbUMXZM=C#s5zzCrf2wW#`3;@2Cn(SrhTx$ax|WP3ep5 z+ZmHHTZktk)b%O$8#gYDWy|poiN}`WpNaTq9uo*~;8cv}*t73|eK4c<`O_-SKmUB3z>PlF8j1ECiQ`l6H22tR{JC@MyS4AmeQVn=u!hNe zMi2X|H&t8RLwVfK*rs-;)+G_*y4CoQ^kUKjIRn45;D~dm{(h0xu~XY z!T04jud${%-clAiHTh8(|2xa7;!Vws^~-au;)XQd@^PmZm6uGJI&((( zxQT^RCX6r2vI?7<4LME}t@fe3AH3_v6Z@%osmqM)|byg%KF8N z(LpP`fnzvNn?BgX8|RHl6+Yb~b*{n~rq9 zosq&5JE2fJJKPS-4DK-yDp_mum%(3;0_cm3kIYcJjBva3NV~MOc9GORvRRh2P`gOD zxJ@jn46OHQZIbKaFC))~i;X_wmeF4h>b0(7zg;MjvabJk`8nwa>eD+#ef~G~W!zh; zuRkuVZ%gg-eQo@Ih0b5UsVU;)_sKf=`7S4+RIuMADt_WCoDEFQ~3xIaaVnSCs2 zB{mASHI=~A58Ila&@m^Ic*D!vm_&m_c6jXby?t_L4Ev0|xA}~BN1|=bbXD`Q!^=sy zUIn|O)7&g^am+-r96?QQB&Jnuy+Jkp7`wZ$H65~#MV8J-F|EOVeb5lNcnXZd}M zg#tck&)ax82p@#8vU`*d`EXNy(^&Z7-{^nREtw0%vgS5{#XumDu$*mWY0cz0H17lzkDP+E;K$T(6bf!~(OQ z6aimussp)Mbrg+Yw6n42ZT<+bNGN4CQKJ#_h}dC85dwmVhS&SZGNm|!V6-i^BD*yF zv}G=LGXb1RpgK?oQc(v2ufuIwCBcr_{L$@?q@Zo;wcKV%P9=~TaASzlis}&@Z}W#r z-6S=Gb{0mD)qqEWag!7&Lp+1cX+kPp$PoYkp#7g2w386xU~lk^7OGQp0p#$H)TDlz zx-X>|wBO&CsCC`2;e&-t?IuMR`F=P4E?Z#S{D>|~rti=K3FTu_u*(`^QkV75RXWa- zJo=(fbs+k_xyoo~(Yd?%gT{y>XdGGgSa98e^+jQD^5jigPp}UFH;?esXuBx zOzxJVMs*;!-#1U0g1);-mZ=1)1G&v)eFmYY5NDnPm@B(y5UOQ&=4F7Nn_a>h**$~s zph+b>Y*GnNn$+EZS4=A5uO{^%;B%8oFvU7*0%liW<%Z%Dtd!~Pavnjo@34Qiu<>Ob zIK{G>hgnvO?>6T>d*3oZ;{E2lKkrv?vBJFL9A*!B4mgs`7E{bbfVu58V2xEQRvf9w z-p#GRfEgTT18j$j!Cq@?E=bK3CroPBmt{%SyHgH^$b##Z>tJay`dY z)YeX^uUlHv*u12o_O#{A@zdkY)%8_{7BvYusfWyOjK^^|zIjA>b5eR!yt%y6tRj{3 z4!y;d7jUM;&nv25GOspX*w|RH+*(-W6DGu)$K%mkz3I>FRmg!VR*@5tioEX%$3bs z$fDOTX)cY|u^>|$YZhY_4gW8Ir60!?waSWGiH|9x`e(qnR#Q`1T3@%oA4Zc}Tw7n! ztlS!1RJ5kYnb(ienpI4VPe%h;)8e&pJOsnW7872$QF&9AakUjqSlmqND@k=%6Vsa; z;dJJVVl1mQqPZID7YAEu!IFx`s&aM=vF8g)p_M3?RbQt|YwSFw^$0i&Vd1r|O0xMX zQ#hq)T3Ja^d1={%^6}HAl}!uUodsiwXz7X~gJ$aHud+3MS!KMT83Ba%%Ep>`adv=` zx@Lc9Q6Mi=*1~$}E-2g#Jk4U2mp5R&x4fykWq$ReY>6T4cz+6<$2c_sqmZpWDm^genbuh(ELnSDu;i;*3MV%IbmGLso zO7^ZRrsI}0He%GzkbksM*i=-3wdy)|@<5yV*NL^W9OcyK0wHCM{4I%IRXYz=Yr;`8 z(TR!+XB3tug;K|qHyqs7PHqwZsAqdiLwM5#TT~_oX;%~1z_FU z&g3AH(s=#B8=uTzIvZ&hqwiSY zSuTI+7qSi}uXf96aV)>%IX2Tf6ON>ujEu08BAg)2O3V-As^gW5Fx(f^EvYPDT2Wq$ zN66SpDdrTmk~F#rZ=n~{Y2&BQJbk>iw1Q99B}QV>T*_uKGq2CYEKAzP>rx1i+o2NO zxMWIknN?U?RyK9~wDPIb#!oGrHom;Dv=p}(rj$)7ABWx33dc>JZYc#*=;?(eQxX%S zG3oVWZ&pw4^}b?Z0-c0|cM@)V+C@HNUoEK@-f&-JC#nzkTUzzV<_R=LO`p=1N_D2<_42aH zO3q_dJUwxbV{)j#yjG7}SLa#t>!zYwMe+G~meU+)CFbslgtn~SzG3s7KK}HwX>&L- zbWSy;Np6=Gj*v5_OrBCUdy3Zw^>&c|bjmoCp@Zivo8pZ)Ss21@!GR#IbR;jVaR+9y zYyW_uCVA$EA&xVzcaiN0CX`xbGr=GIUz%#;IJhE4atKTwuShMb;i>0oOXkmyHx^b^ zp$0mBWcKwA2!(Qtl{CLo_CnmS|Mkz41_t9`D4L)n#s%aFw1I) z*Wt0&1?G06wXn&X!O_~a@#gr1+WL8VVpEH||Ev=SO3-d%!Zv5+zC*t?wZ1`mRWToE zPE;uoRCGP>7HQz1>A!m_<09c`R;pt#raO10bLS|pM&68xI(XBl_7nHqzS(N1Krwj^ z!5ik{(!?xj6l>IcllxH@8F~_2j(^l;u@_nk=b0u63~&FmgMt}nW{8_U=D+SeucD?I zmn{rei)LoQlRFB~pghjPE}Gn!I~`AJH`h0gXP@zgSZUex8Rf-g<7Q5`rY>o!_BB_1 zow=<{8>VdjuIMFt<~8bGAMpoW3V`#t2~%dq#>M1`bF|kI1V^rhFj*vqi`7`Opc+Aw z4vFKBIeM`R`{%<#o^HEO1SIuM&u{X$Pej|ASKr)>)0UvgS?r-+b&_-Ydv%puASTWY zaO_DsMVmE#+G%Ce$9o~3KBI8j4B9sF^A8|YT<3IFA;rjDyren4jN`qeZfX4@JnrF+ zcP}RfgYWdPX#8n2CnTjzFDb?Sb{uDLedk@s@>qqdP;D}ANO+<1_q--tH_Pc7FJ9w~ zbrrQmxX_(ifzx;QmjBeknMw66o673wnULR>_iyXGGa=aY4YlOS*d3Y@1aqaHn3VEo z)z{*oho=0d#>)H!HO=|z2m5$Bq;Z~Ha=4e(Y%H&qRw17v@p(1vqUV=jdR^GZ@l66| zK=7oJ#3uYafEOS#+|11B9!W_|^lP1OH0FtPFX-$6?(kJ|;2fL=-HW!wiP893Y+&}+ z#1x5RqgF9-jpNgzGkW1rS1@fxxs=Sz7&_S{u1{G2>A$|~x5U8G(`lX?cmv+GN|rII z-Gb#!WHqNp{)P}^{@D;^mPRmED9Q2BPw{m%i~--HJc%aLf+t=48;j-Wxt&8@iyLC%}U_SKtX~@Nq9+?=(R$ z7I9AbBY!`X^kbrdl}Xb^(fH!RnWZvqVbbx>S@C6oSwJ2clENhVnt!+~WDS#!lIFoQ z-wA;^K5GAv$*!WdrpmpN9beak$Hin+jjL#=sN~r@I-;+m7UO{}b9U-ZNfU6jFuq8S zY{~70`e?K1Sad7sjl@J#i4V7>(40C!nUcy$vac0_42lwc+wd1n_+OI*05 zddkgOcpi+Qmfn+%-UUp7w>QY!8;tcYw;+i?vee0)S1T=D%IihRp>$UjQ6CcpEPZ47 zrWu1O(H)ZGVJ0enPw-9d?6qbDunYUgt~V>En)dwG5IenQOn$J?Ow>GrB-u^)Nv@}y z@AC90shy;oaMCeTGNyIUThh~ymUjZmk?mDV<|{Kq&G9_RxW88?4ge)h?vuD>^H~S~ zb)Gk8C7RJUJqG(}pcB{E9sNA01c`&&G=dorNe3Q!N_71sle|bUO=hYng`zR-R+Ix7 ze1}zBg6RD>RMK=3sf#HICcH+T97>E5{u4t+I+1aN@g+xGxd2EmZ-Sq^I-XcZomtn2 zI|*1RYcx|vlf*o6<0g1cg0GmF2FZJ{7yrEQ>J) z-XyC&S(W6Tu1A>`?$n^`8M+Cfk^}3rv>mAJQ3ow=Q9v8gnlNtMDY4$TuL5U~a}EnnPRF%Q_>Xt3Jd z!!=2>HINVJS_9`{1!G_peuuoEykZ{Cx|do58{@T_Qd2j--Y?hk7r~;ZiGit3Y6ccg zJAELO74rtR%%KOvtEpP{13a2s%ndN#Um@nz#v^uP6R@chFhO#1t;SpL|sP zbTQcq`t+CF<&6p%qDKv|RMuF!lr=U>20v6) zW&Mac`j}d|#ARvXz!3E3zq#sTrSSJX%%l9dCsg0(&Ex!luOwc|Na}iG&{?n(xU>}h zzK^Pv^PhVA0(I16+yXC!)8undpG|U8c=ZDDy*@qG4|+^u9u-*sdg}K@Hi?(Qr$4ku zaZ}VXX<0kyI5}j=)D*sdh@R5DxvKgh&&v7{PJK-Em*Rx=Xm_bdDZRBsJgP-GbGjGX z`WQ{nt-rBS(Nh%Q$7IoZ%N@d?OTBTJdO|fh=v7UayMRaA(DW4LbMGAbPpWj?{%A9< zBBdR_(yI~gHXUsTC;m)NX~w5Js)^*$te`o6gbg8u-P9y4rp_%X3hHT6m`psxlZc() zjki|)eFaXCQg}#hjl`oO<6TyLpR)w%2b}qc^*l@GDg2;;gZyXWvPS4nsI9N`iw#Tg z0w64}`_piL45tuDNp6a{0Dv27Ab+oi6FO@keu5ewh|7-wOVS3=JzUO2Oosw^QYW$@gWZ{@{ujb)8{CyUeIRZ^FusdEV+4TkoG3K&V0Jj zzJ2UkE5YIOuI}dAU=m*^{<&(;cfTw@*heG z-6ZV$?QQ%6Ubu@i+QSQkJbRa5pZ54@Gq*cWv#glxnJ@Rz*`Gl4+gr8M{4SFAnC_Nu z8TM(<4aKvt=il72Z$u*Y8|a@Kd90u7!}Yttmqy-t_-zZM-)wwbzaL|tw%vNXKzpt; zp@%G+8GlGvb@?E=H| z>OmgsL0jD1dhji=e!nCBl&A-PazGyQy`X;G_SgY?W0CG|uDv@0_9ns}ABJWRmsZap$#Zz2up=Gtom zo(=8;*mECp zhuX8(7_heo_V|$cUHEiY9_?MH_5iZo0DByd?&g;7NyGE%u~F+mTijgUqu}}Dm-*+! z{Bol5=r@Fk+20E_z|d%#`{_F~}Ng%9U=@@Vg{DW5macf+24qc3iqjbE=G zOadZ8)2hU%RvGD88SACVoeDOd%_P`$F>~5~Tp#ghSeR1J2$gRg&Y7f9~Up*GEx6IcbgM9Y(s6DqH zr7hIMMgdSKuO8&F9<;^Ht;c@@e%Jfz!DF^t5B}(tF>>pHr#8GFdHC)11kc~Tn|<}* zk33v^#cI#3$C?)E(O`I9J;-A{+#ih49yh)|)$ezwuO4`lrssEu`gQAZ1MInNOFOQ; zUj*#!@zvv0pS|CzJ+~e^TByfcMj*@|bU6T5@~rY@r_M z;Q8Z{`9flxkM-H>q4wN*9BQE+rH1F#gFKdpwz#?Vm>BTe8-Cq!K2CYecdPnMXJ%~Q z!XA%r?&jKS2-q9ptH*ed-MCz<_S||5o#0wB=#KLz4bQ6wc`OfYadZ7X3Z6fHXZq?f zQF+W4MFsrhV3d+!G9Rr~5O30$`xX==}{M|BJJ7-V=}J;-BuXp5WccK~?) zdaU-<<8vd@SRUHq=GNo3fZs=b z^_ZqS=KE6p0%W@r_EPn$KL+gW^wnbqa=PvDvD$O%vA2bKbjnDccgbUUXp5U$4+lJd zdmQl9gTI=0{nioXJ<(?jyYBe7-tfHk zAdmH+EpD#gwE@4KUrdbipDK^}4ya$ZJ=()we;U%wwfFmgz22}F1LrP$_=8S2E`L*d zZav1ro_}-ekqPJ6_v%3&lEfDIuHOg}{qdXVt4D?Mm~S?|XxpvF#EGfTO9lq)o$0Gb zrO)2!YR|35GT8HPZatP7o>vd@kYv#oH@6;*Nc7iZnXex6mB)N9;mco-RTEQ>k6Q!w zR{QEv?X&l++H>piDD3$+w;o>^o>vd@kR-p(CEu;b7fAHiW3#UwiF661V{@|f=hW6v8OG1yC0j|T$wI>TNJ`8m$d!^f@1GiuMR$3)okZ*D#I8J<@U z@>m|);^x-lE%5N?Z6kd3IA3|p*FGz`UrmL*RQ2FLy71eZ=&Q#HpS>)#=hkBx?D;ph z9z6}us|R^34{dRC>(L!Nzu#(KJ@`HtH-43YdaQ!Isba}|x%Nf}>@9=6iJ-7OF2={T zhqsH#cysHqyM=mOWO!aZ$YVWdi<|5B{D9vbzIt4yJm%wz{TL&6eC&a}9+2J5wRc;< z-fmxeTmdq9wD*wObL;VK3-x%}@Vt7E$NaR#&Gq|Y!0$m{J$|M<=4;8=CuK| z#m%+%aljt`r^rF**&bIZkM^?Eo?DO7$w>5VZoe90cwRloWB#j@>-xQcLxm6?=SFi>-%BA-b9?dhS28j=C<4W0egpE#=l1ckM`E%L9T%|o=-Y|-{R(8)-T<{%pa!nO$>At2OzK8^{EP_r-MKvRu2xcAzl8zbU%~Tl zE{|_)LbErxI`Rg%0?_4g&Dz&JtPC7nDv;ORTprQw^VF@{i1W#)W!;VaSMgze+v39* z`|WLg0RLHzO5I$0uI!>eJz{-!#7!rLz0#W0a8gOA4~y?a9=|o}eFYGEX$h*xI7#`t2TPv%tyDNC3l@HAE(r)zjxD&R}xqVwWX$GObO~8K} znX~Ah_bEcq)Bh))jW*Tknc$GO=YIZwXB72$6&_UVsh4B@E6^Bu~)MP6a?Tp%HzXRS_>8)e>1 z=oeczslGt+S6W+C?k{qg^-Pj{j@wT7uY5}XiL zCnu?F?6EZxTiEK55U>~a-q3E6!{|B5@#}2OQhQ@T2|-VbBMcqiovnq?Z}a3}e>&FF za3^f}CK!>A5BLkVceg!SW`0Dk)*>M2~6Y zUIBl-#D2_U^|F2r`yYF9(0(6J!<}$obcWH&$?@-Rt=0ON{={C8*uvg_3@~Y78Qp&U zpn$zWfp`qE_}|OE_Ob-aJH*p)C!BPKLiwbC{gW*DuUX)-kA%EcX67b8(Q}M^vZT9T zVXWpR*Z)*0Z=zLBwf=zeo`{dxg5@3MDg?v6nT82rYiz*&*ns`9@;}^)TC{&!!2Y;^ zJU(E5y!9$<(VU6L_yC`?V`2--6@y=%6tFibP~J%v??+a&Sl-fvG3^k5h<Cc-YQv(SCEl{*r)vUcml&0sH64 zGc}!Bw4Zzu8@u+D((ycX?WlrV<9u$*lqlES#!Pqu%tH5<0r zo>TD&d8+{?PuRLNkr{j84-(_ODAA!(Ldfq!USDoR9jq zFs^u$&)|3koY=y+f=$-1Pbje$mMhXkQdq7i{W7lz6IHo2IM~mju$+rEo9`fC-Cj|s?puEO2O?;DVd1MehZpYr&h-K{eJMudSmDJd|%-x8IM8&3U*B>mAp z<|!R_@=*-^WeeKHv`%vK(1!cd4p5|x1`SCvlJvU+aE7uZgNDg>a)DDl^bV>Neb5NW za5BFK7bH0_k7Xknj}YTq$}m_u%3$#|SbPmWNwi{YuoxSBGJfOfMiT$gk}u!Flfg*i zj}Xh3)UjgamFR>GjRn?X{BjZxAuouNm71EfsZPAg%+MpM)!B$HKL=z6^(ZkYf*wh?+m$@ zVn|Esgx2DZ^$HXHu-tgopX$55q+0VD>no}%EAYNH{Utv_6UUp0;+|YlRaK1F3e;6K z;+>i0i}9acE$N4;!#c>StgXkZ5tE#_9okJa6>w9fwO#w1A-sp&{Z&8^@%}Nbf}ia@ ze9j%rS?TzM@Rd#6g@5I&*g-Lu_!6!uiJ3S)X!iuWnN6N-OS zd_(bl#V-{3Tp{g66^~c!r+BjB1jU((m5S#ou2j5Qaf9N0ijOP)QE`vr2a5kzOiMH6 zX|I^4I9RbzajIguVx8iJifa`4JR0kFui|5hI~Cth{D^_*dk8UCLt=%M{BM>lIfju2sBE@d3r{in|o| zDSoPWL@|m3miSl9R~(~QrdY06ueefit>SHp4=8R|+@-ir@l(Ykic#Do690<%ienVZ z6w4Ls6;~>*RlH5{0mbc#yA<~+eyVsxF^WY4@voS#I7YEdv0SlUai!u~#oH7gP~5J# zOL3p#r;0}uqfzy*n6EfSu}raCv0ibd;#$Sq6dzFBuDDBapW>&AM--#DIFtG-<|~d- zEK@93tXEvAxK{Bt#Rn9(EACR9|Ei{xOO%#es?=6(=d4sW@M; zS@9CZb&9`I+@kon;!efCD88roxgu{-u{>=Q`zhkGRMN*P7Aux2PE$Nn@f^h}#f6Fu zic1w&C|;ttT5+x7t%{oz?@_#8@gc>>6t^orr}$^ZR}|kS;u!gk;`_uuS=PT)e^}-J zs+@rf8R~P0h)ZW;JN!RL#hB{*sD6mbBUHw!i{v{)@hsKPRe7o6MMT`*y+rW}BK)pZ z{Vgirrt-ZiKcMpCD(_JF55#=S`m^FL)$dXL-&H=K@)tzhRQgKs8`VdUCjEhk@;EA= zpx9f}2dX@bc#376tT;;b#j2mGa=Bt$(-#v9E$dvxC91zj^*>X2t;)Y3PQZ1Q;;&SH zkLtIn{9BcGsQkRjFA+=eKXnxUqWXQR|48LeRsLFKYdG?uA7l`x;rdZAN<@4*tG>I+ zy;R03jp&D~Jcc;ivas+ZIDv@#Q;D#DmdbNgUZnE5DlaFVZCMv8Uab0`tNuonZ&CR! zmG4veL1HET53=Ips{bF=zo_ynD(_YK?<#*ptj4%e{9N_ls6HJx%vhh+MAWCF%3W3N zL9D}bB8vT0KTP#wRUWVMRF!9`d^WKe_ih#As;^W1GL zqw<3)KdSN$A|7UWR&l55UsnBImETeM6O}(#`D^0kmi3)t2)FJfK19Yx<>OTDsd9gn zhY+vA^Wlo8s=i3|Q&c`%u~O3)5!YE(y<(Ht@AYs{U@(Z&Ueq zD*v9i0qYow&#Qiy>fcm(pUVFr-fmeRDgI0KU#Z^4+`+hH5D}L)#LYN9Dt1(TH`Vu1 zIbY?Ii1%C8DT2tS{R8veI3nh)Swze~ zjl|iO^)n*o16fz8v@BUq!T5ZI=@@6cPr~t%#&wJ3IDQe)pNA09FH4B%UsXi(m-C6} z2kVGv-@A#ox*`l4My8yhvk!UIp!H!=G%bu@CkUnnAi>P zc_7B{j4v_QlIP&UxVGI&xw|QMIM1>krQE~(o4D|acvh8iPg9?8FRUw4?v39?5c}ZS zU1DETzi>aZP8#lyL~MQ04`o9+rCm@?Rv~M@WyOf^Y5Tmd?Sr_CKsw7mk~jok*!rR$ z%LY4{*va|_<~QO8<~QoJN0(UvJ6Q*`opCPBt?x+&*%;EVK2$qs@2*g>y~Pg7ITSL> zA>|ou^7X~|k?kY%9Bbb(iTF#sQ0N#4%!d$K;UZyMeG3iJuf$=$mK%J8(qez$))(VZ zHt?9A?JDId36!VI(E64dq}^=t_iKG%SMtA;h%1?WF}`I3zdd$nU+O(W%ZqZeJmH@h zT3^fqvbDsYt9<0+))(`IY~cT>@>C}HN#%(L%CpGu`d0q{|J*=%>Jofu@BNl_ERwQ( z@hPC}#=kkicgrLErGa)`VR(Hp@5zSxx_pVJ+GjtIcwVA>%#T5ScOyhu-=5%SVK-}k zqCdwdqd&`dKzj|Q{ISmGKn~HYPw>CiiT^ae7tZ<@1Z;gb8)O{axXAo*uO3ej?-(fI zt%le4{sbRWn~akJ;(qn_o+ZysbNrmi^n-f5fZV9Oi-?$yE+eA6w-BMo|fEDz%me%A2%KCS$ZbY6VUjEB%pGvD+4gnY_F zi8y{SZj^sY#BrioS~u?_0{4M;RB&j0?|i zSWn8VC(m={s$50HJhw{a%ZQlAHml6%ad}-M_tTL71HJR;AF z3RE6S#5}?GyHG!ahB0RsEs`3ot{phbMHxSX@d`}4TuOmK{8;g8A_nz$is_g*C}$}itB6;LOZth5eH056 zhboR!l>6?mGezZTigOgtR^cp)D-_o#%JnDoH>rH9;=PK$QG7)4F~yz4 zYRvzNuPMrXe54;x`4h!26u(mZPBD~b?6gztpx9M0rkGE}ab<`i-}y&*jAEJMbj6=2 zo}(C7tWjL1xI*z##VZxBQM^uZ6A{O;yA(JA6!$8=tN4N9zZJh$v@?wTG{tPiwu;?|I8Vq^ z?5CKoI7V@t;v~f>if1cUC{`=hDqcXudB;k{D;2L&yjAfw#k&>nReX$y^OUC)pHuv! z;+u+ZE54`5_o^`8S45oGe4`l7G;)SwC&l9wyDRoo97eny#~Z~$#qo+W73V0f;fuXvFn z-~T~7KT}+%c!T1tit;=Pcz3IOui`evM--nWK8^Em#odapDZZz8KvAAw0sjk?F|4c* z`jU(8d2DB<vzgQEzVk^Y={3sAslfTO!U^+beb^qTXEC8AxPRNO&Cre_s* X646dCDDEbry -#include +#include #include "glutils.h" struct engine { struct android_app* app; - + int animating; EGLDisplay display; EGLSurface surface; @@ -69,13 +69,13 @@ static int engine_init_display(struct engine* engine) { engine->width = w; engine->height = h; engine->angle = 0; - + // Initialize GL state. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glEnable(GL_CULL_FACE); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); - + return 0; } @@ -84,7 +84,7 @@ static void engine_draw_frame(struct engine* engine) { // No display. return; } - + glClearColor(((float)engine->x)/engine->width, engine->angle, ((float)engine->y)/engine->height, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -108,7 +108,7 @@ static void engine_draw_frame(struct engine* engine) { #endif eglSwapBuffers(engine->display, engine->surface); - + //engine->angle += 1.2f; } @@ -144,7 +144,7 @@ static int engine_do_ui_event(struct engine* engine) { } else { LOGI("Failure reading next input event: %s\n", strerror(errno)); } - + return 1; } @@ -169,19 +169,19 @@ static int32_t engine_do_main_cmd(struct engine* engine) { res = android_app_exec_cmd(engine->app, cmd); break; } - + return res; } void android_main(struct android_app* state) { struct engine engine; - + memset(&engine, 0, sizeof(engine)); state->userData = &engine; engine.app = state; - + // loop waiting for stuff to do. - + while (1) { // Read all pending events. int fd; @@ -201,7 +201,7 @@ void android_main(struct android_app* state) { break; } } - + if (engine.animating) { // Done with events; draw next animation frame. engine.angle += .01f; diff --git a/ndk/samples/native-plasma/jni/Android.mk b/ndk/samples/native-plasma/jni/Android.mk index 34e85a1f5..f78df901b 100644 --- a/ndk/samples/native-plasma/jni/Android.mk +++ b/ndk/samples/native-plasma/jni/Android.mk @@ -18,6 +18,9 @@ include $(CLEAR_VARS) LOCAL_MODULE := native-plasma LOCAL_SRC_FILES := plasma.c -LOCAL_LDLIBS := -lthreaded_app -lm -llog -landroid +LOCAL_LDLIBS := -lm -llog -landroid +LOCAL_STATIC_LIBRARIES := android_native_app_glue include $(BUILD_SHARED_LIBRARY) + +$(call import-module,android/native_app_glue) diff --git a/ndk/samples/native-plasma/jni/plasma.c b/ndk/samples/native-plasma/jni/plasma.c index dcc8f6fdf..0ef9788ae 100644 --- a/ndk/samples/native-plasma/jni/plasma.c +++ b/ndk/samples/native-plasma/jni/plasma.c @@ -15,7 +15,7 @@ * */ -#include +#include #include #include @@ -374,9 +374,9 @@ stats_endFrame( Stats* s ) struct engine { struct android_app* app; - + Stats stats; - + int animating; }; @@ -385,20 +385,20 @@ static void engine_draw_frame(struct engine* engine) { // No window. return; } - + ANativeWindow_Buffer buffer; if (ANativeWindow_lock(engine->app->window, &buffer, NULL) < 0) { LOGW("Unable to lock window buffer"); return; } - + stats_startFrame(&engine->stats); struct timespec t; t.tv_sec = t.tv_nsec = 0; clock_gettime(CLOCK_MONOTONIC, &t); int64_t time_ms = (((int64_t)t.tv_sec)*1000000000LL + t.tv_nsec)/1000000; - + /* Now fill the values with a nice little plasma */ fill_plasma(&buffer, time_ms); @@ -429,7 +429,7 @@ static int engine_do_ui_event(struct engine* engine) { } else { LOGI("Failure reading next input event: %s\n", strerror(errno)); } - + return 1; } @@ -453,7 +453,7 @@ static int32_t engine_do_main_cmd(struct engine* engine) { res = android_app_exec_cmd(engine->app, cmd); break; } - + return res; } @@ -461,20 +461,20 @@ void android_main(struct android_app* state) { static int init; struct engine engine; - + memset(&engine, 0, sizeof(engine)); state->userData = &engine; engine.app = state; - + if (!init) { init_tables(); init = 1; } - + stats_init(&engine.stats); - + // loop waiting for stuff to do. - + while (1) { // Read all pending events. int fd; @@ -494,7 +494,7 @@ void android_main(struct android_app* state) { break; } } - + if (engine.animating) { engine_draw_frame(&engine); } diff --git a/ndk/sources/android/native_app_glue/Android.mk b/ndk/sources/android/native_app_glue/Android.mk new file mode 100644 index 000000000..00252fcb0 --- /dev/null +++ b/ndk/sources/android/native_app_glue/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE:= android_native_app_glue +LOCAL_SRC_FILES:= android_native_app_glue.c +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) +LOCAL_EXPORT_LDLIBS := -llog + +include $(BUILD_STATIC_LIBRARY) diff --git a/ndk/sources/android/native_app_glue/android_native_app_glue.c b/ndk/sources/android/native_app_glue/android_native_app_glue.c new file mode 100644 index 000000000..d7a839171 --- /dev/null +++ b/ndk/sources/android/native_app_glue/android_native_app_glue.c @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include +#include +#include +#include + +#include "android_native_app_glue.h" +#include + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) +#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "threaded_app", __VA_ARGS__)) + +int8_t android_app_read_cmd(struct android_app* android_app) { + int8_t cmd; + if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { + return cmd; + } else { + LOGW("No data on command pipe!"); + } + return -1; +} + +int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd) { + switch (cmd) { + case APP_CMD_INPUT_CHANGED: + LOGI("APP_CMD_INPUT_CHANGED\n"); + pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) { + AInputQueue_detachLooper(android_app->inputQueue); + } + android_app->inputQueue = android_app->pendingInputQueue; + if (android_app->inputQueue != NULL) { + LOGI("Attaching input queue to looper"); + AInputQueue_attachLooper(android_app->inputQueue, + android_app->looper, NULL, (void*)LOOPER_ID_EVENT); + } + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_WINDOW_CHANGED: + LOGI("APP_CMD_WINDOW_CHANGED\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->window = android_app->pendingWindow; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_START: + case APP_CMD_RESUME: + case APP_CMD_PAUSE: + case APP_CMD_STOP: + LOGI("activityState=%d\n", cmd); + pthread_mutex_lock(&android_app->mutex); + android_app->activityState = cmd; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_DESTROY: + LOGI("APP_CMD_DESTROY\n"); + android_app->destroyRequested = 1; + break; + } + + return android_app->destroyRequested ? 0 : 1; +} + +static void android_app_destroy(struct android_app* android_app) { + LOGI("android_app_destroy!"); + pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) { + AInputQueue_detachLooper(android_app->inputQueue); + } + android_app->destroyed = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + // Can't touch android_app object after this. +} + +static void* android_app_entry(void* param) { + struct android_app* android_app = (struct android_app*)param; + + ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + ALooper_addFd(looper, android_app->msgread, POLLIN, NULL, (void*)LOOPER_ID_MAIN); + android_app->looper = looper; + + pthread_mutex_lock(&android_app->mutex); + android_app->running = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + + android_main(android_app); + + android_app_destroy(android_app); + return NULL; +} + +// -------------------------------------------------------------------- +// Native activity interaction (called from main thread) +// -------------------------------------------------------------------- + +static struct android_app* android_app_create(ANativeActivity* activity) { + struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); + memset(android_app, 0, sizeof(struct android_app)); + android_app->activity = activity; + + pthread_mutex_init(&android_app->mutex, NULL); + pthread_cond_init(&android_app->cond, NULL); + + int msgpipe[2]; + if (pipe(msgpipe)) { + LOGI("could not create pipe: %s", strerror(errno)); + } + android_app->msgread = msgpipe[0]; + android_app->msgwrite = msgpipe[1]; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&android_app->thread, &attr, android_app_entry, android_app); + + // Wait for thread to start. + pthread_mutex_lock(&android_app->mutex); + while (!android_app->running) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); + + return android_app; +} + +static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { + if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { + LOGI("Failure writing android_app cmd: %s\n", strerror(errno)); + } +} + +static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { + pthread_mutex_lock(&android_app->mutex); + android_app->pendingInputQueue = inputQueue; + android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); + while (android_app->inputQueue != android_app->pendingInputQueue) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { + pthread_mutex_lock(&android_app->mutex); + android_app->pendingWindow = window; + android_app_write_cmd(android_app, APP_CMD_WINDOW_CHANGED); + while (android_app->window != android_app->pendingWindow) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { + pthread_mutex_lock(&android_app->mutex); + android_app_write_cmd(android_app, cmd); + while (android_app->activityState != cmd) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_free(struct android_app* android_app) { + pthread_mutex_lock(&android_app->mutex); + android_app_write_cmd(android_app, APP_CMD_DESTROY); + while (!android_app->destroyed) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); + + close(android_app->msgread); + close(android_app->msgwrite); + pthread_cond_destroy(&android_app->cond); + pthread_mutex_destroy(&android_app->mutex); + free(android_app); +} + +static void onDestroy(ANativeActivity* activity) { + LOGI("Destroy: %p\n", activity); + android_app_free((struct android_app*)activity->instance); +} + +static void onStart(ANativeActivity* activity) { + LOGI("Start: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); +} + +static void onResume(ANativeActivity* activity) { + LOGI("Resume: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); +} + +static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { + LOGI("SaveInstanceState: %p\n", activity); + return NULL; +} + +static void onPause(ANativeActivity* activity) { + LOGI("Pause: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); +} + +static void onStop(ANativeActivity* activity) { + LOGI("Stop: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); +} + +static void onLowMemory(ANativeActivity* activity) { + LOGI("LowMemory: %p\n", activity); +} + +static void onWindowFocusChanged(ANativeActivity* activity, int focused) { + LOGI("WindowFocusChanged: %p -- %d\n", activity, focused); + android_app_write_cmd((struct android_app*)activity->instance, + focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); +} + +static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { + LOGI("NativeWindowCreated: %p -- %p\n", activity, window); + android_app_set_window((struct android_app*)activity->instance, window); +} + +static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { + LOGI("NativeWindowDestroyed: %p -- %p\n", activity, window); + android_app_set_window((struct android_app*)activity->instance, NULL); +} + +static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { + LOGI("InputQueueCreated: %p -- %p\n", activity, queue); + android_app_set_input((struct android_app*)activity->instance, queue); +} + +static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { + LOGI("InputQueueDestroyed: %p -- %p\n", activity, queue); + android_app_set_input((struct android_app*)activity->instance, NULL); +} + +void ANativeActivity_onCreate(ANativeActivity* activity, + void* savedState, size_t savedStateSize) { + LOGI("Creating: %p\n", activity); + activity->callbacks->onDestroy = onDestroy; + activity->callbacks->onStart = onStart; + activity->callbacks->onResume = onResume; + activity->callbacks->onSaveInstanceState = onSaveInstanceState; + activity->callbacks->onPause = onPause; + activity->callbacks->onStop = onStop; + activity->callbacks->onLowMemory = onLowMemory; + activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; + activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; + activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; + activity->callbacks->onInputQueueCreated = onInputQueueCreated; + activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; + + activity->instance = android_app_create(activity); +} diff --git a/ndk/platforms/android-9/arch-arm/usr/include/android_glue/threaded_app.h b/ndk/sources/android/native_app_glue/android_native_app_glue.h similarity index 71% rename from ndk/platforms/android-9/arch-arm/usr/include/android_glue/threaded_app.h rename to ndk/sources/android/native_app_glue/android_native_app_glue.h index 2b58e9c2d..e30e9603e 100644 --- a/ndk/platforms/android-9/arch-arm/usr/include/android_glue/threaded_app.h +++ b/ndk/sources/android/native_app_glue/android_native_app_glue.h @@ -15,6 +15,9 @@ * */ +#ifndef _ANDROID_NATIVE_APP_GLUE_H +#define _ANDROID_NATIVE_APP_GLUE_H + #include #include #include @@ -22,6 +25,60 @@ #include #include +#ifdef __cplusplus +extern "C" +#endif + +/** + * The native activity interface provided by + * is based on a set of application-provided callbacks that will be called + * by the Activity's main thread when certain events occur. + * + * This means that each one of this callbacks _should_ _not_ block, or they + * risk having the system force-close the application. This programming + * model is direct, lightweight, but constraining. + * + * The 'threaded_native_app' static library is used to provide a different + * execution model where the application can implement its own main event + * loop in a different thread instead. Here's how it works: + * + * 1/ The application must provide a function named "android_main()" that + * will be called when the activity is created, in a new thread that is + * distinct from the activity's main thread. + * + * 2/ android_main() receives a pointer to a valid "android_app" structure + * that contains references to other important objects, e.g. the + * ANativeActivity obejct instance the application is running in. + * + * 3/ the "android_app" object holds an ALooper instance that already + * listens to two important things: + * + * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX + * declarations below. + * + * - input events coming from the AInputQueue attached to the activity. + * + * Each of these correspond to an ALooper callback that returns a "data" + * value of LOOPER_ID_MAIN and LOOPER_ID_EVENT, respectively. + * + * Your application can use the same ALooper to listen to additionnal + * file-descriptors. + * + * 4/ Whenever you receive a LOOPER_ID_MAIN event from the ALooper, your + * code should call the function android_app_read_cmd() to read the + * command value and act upon it. This is normally done by calling + * android_app_exec_cmd() directly. + * + * XXX: MAKE THIS STUFF MORE CLEAR !! + * + * 5/ Whenever you receive a LOOPER_ID_EVENT event from the ALooper, you + * should read one event from the AInputQueue with AInputQueue_getEvent(). + * + * See the sample named "native-activity" that comes with the NDK with a + * full usage example. + * + */ + /** * This is the interface for the standard glue code of a threaded * application. In this model, the application's code is running @@ -195,3 +252,9 @@ int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd); * the main entry to the app. */ extern void android_main(struct android_app* app); + +#ifdef __cplusplus +} +#endif + +#endif /* _ANDROID_NATIVE_APP_GLUE_H */