From d3d58cf7d3a508bb855c2ad626205ddcbb3bd237 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 7 Sep 2010 15:30:07 -0700 Subject: [PATCH] Update to follow ALooper ident change. Also the native-activity sample also has some very simple code showing how to listen to the accelerometer. Change-Id: I0629b8bc40cddd66233c1675cd5e8b42a9b722d8 --- .../arch-arm/usr/include/android/input.h | 62 +----------------- .../arch-arm/usr/include/android/looper.h | 16 +++-- .../arch-arm/usr/include/android/sensor.h | 2 +- .../android-9/arch-arm/usr/lib/libandroid.so | Bin 26336 -> 56544 bytes .../samples/native-activity/jni/main.c | 53 +++++++++++++-- .../samples/native-plasma/jni/plasma.c | 6 +- .../native_app_glue/android_native_app_glue.c | 10 +-- .../native_app_glue/android_native_app_glue.h | 48 ++++++++------ 8 files changed, 99 insertions(+), 98 deletions(-) diff --git a/ndk/platforms/android-9/arch-arm/usr/include/android/input.h b/ndk/platforms/android-9/arch-arm/usr/include/android/input.h index 243c33c3a..5b62da443 100644 --- a/ndk/platforms/android-9/arch-arm/usr/include/android/input.h +++ b/ndk/platforms/android-9/arch-arm/usr/include/android/input.h @@ -623,10 +623,10 @@ typedef struct AInputQueue AInputQueue; /* * Add this input queue to a looper for processing. See - * ALooper_addFd() for information on the callback and data params. + * ALooper_addFd() for information on the ident, callback, and data params. */ void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, - ALooper_callbackFunc* callback, void* data); + int ident, ALooper_callbackFunc* callback, void* data); /* * Remove the input queue from the looper it is currently attached to. @@ -662,64 +662,6 @@ int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event); */ void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled); -/* - * Input devices. - * - * These functions provide a mechanism for querying the set of available input devices - * and their characteristics and capabilities. - */ -struct AInputDevice; -typedef struct AInputDevice AInputDevice; - -/* - * Populates the supplied array with the ids of all input devices in the system. - * Sets nActual to the actual number of devices. - * Returns zero if enumeration was successful. - * Returns non-zero if the actual number of devices is greater than nMax, in which case the - * client should call the method again with a larger id buffer. - */ -int32_t AInputDevice_getDeviceIds(int32_t* idBuf, size_t nMax, size_t* nActual); - -/* - * Acquires a device by id. - * Returns NULL if the device was not found. - * - * Note: The returned object must be freed using AInputDevice_release when no longer needed. - */ -AInputDevice* AInputDevice_acquire(int32_t deviceId); - -/* - * Releases a device previously acquired by AInputDevice_acquire. - * If device is NULL, this function does nothing. - */ -void AInputDevice_release(AInputDevice* device); - -/* - * Gets the name of an input device. - * - * Note: The caller should copy the name into a private buffer since the returned pointer - * will become invalid when the device object is released. - */ -const char* AInputDevice_getName(AInputDevice* device); - -/* - * Gets the combination of input sources provided by the input device. - */ -uint32_t AInputDevice_getSources(AInputDevice* device); - -/* - * Gets the keyboard type. - */ -int32_t AInputDevice_getKeyboardType(AInputDevice* device); - -/* Gets the minimum value, maximum value, flat position and error tolerance for a - * particular motion coodinate. - * Returns zero if the device supports the specified motion range. */ -int32_t AInputDevice_getMotionRange(AInputDevice* device, int32_t rangeType, - float* outMin, float* outMax, float* outFlat, float* outFuzz); - -//TODO hasKey, keymap stuff, etc... - #ifdef __cplusplus } #endif diff --git a/ndk/platforms/android-9/arch-arm/usr/include/android/looper.h b/ndk/platforms/android-9/arch-arm/usr/include/android/looper.h index 291721624..287bcd5f0 100644 --- a/ndk/platforms/android-9/arch-arm/usr/include/android/looper.h +++ b/ndk/platforms/android-9/arch-arm/usr/include/android/looper.h @@ -111,7 +111,7 @@ enum { * * Returns ALOPER_POLL_ERROR if an error occurred. * - * Returns a value >= 0 containing a file descriptor if it has data + * Returns a value >= 0 containing an identifier if its file descriptor has data * and it has no callback function (requiring the caller here to handle it). * In this (and only this) case outEvents and outData will contain the poll * events and data associated with the fd. @@ -145,10 +145,12 @@ void ALooper_release(ALooper* looper); * descriptor was previously added, it is replaced. * * "fd" is the file descriptor to be added. + * "ident" is an identifier for this event, which is returned from + * ALooper_pollOnce(). Must be >= 0, or ALOOPER_POLL_CALLBACK if + * providing a non-NULL callback. * "events" are the poll events to wake up on. Typically this is POLLIN. * "callback" is the function to call when there is an event on the file * descriptor. - * "id" is an identifier to associated with this file descriptor, or 0. * "data" is a private data pointer to supply to the callback. * * There are two main uses of this function: @@ -156,13 +158,13 @@ void ALooper_release(ALooper* looper); * (1) If "callback" is non-NULL, then * this function will be called when there is data on the file descriptor. It * should execute any events it has pending, appropriately reading from the - * file descriptor. + * file descriptor. The 'ident' is ignored in this case. * - * (2) If "callback" is NULL, the fd will be returned by ALooper_pollOnce - * when it has data available, requiring the caller to take care of processing - * it. + * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce + * when its file descriptor has data available, requiring the caller to take + * care of processing it. */ -void ALooper_addFd(ALooper* looper, int fd, int events, +void ALooper_addFd(ALooper* looper, int fd, int ident, int events, ALooper_callbackFunc* callback, void* data); /** diff --git a/ndk/platforms/android-9/arch-arm/usr/include/android/sensor.h b/ndk/platforms/android-9/arch-arm/usr/include/android/sensor.h index b4ce02426..a102d43c7 100644 --- a/ndk/platforms/android-9/arch-arm/usr/include/android/sensor.h +++ b/ndk/platforms/android-9/arch-arm/usr/include/android/sensor.h @@ -166,7 +166,7 @@ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type * Creates a new sensor event queue and associate it with a looper. */ ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager, - ALooper* looper, ALooper_callbackFunc* callback, void* data); + ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data); /* * Destroys the event queue and free all resources associated to it. diff --git a/ndk/platforms/android-9/arch-arm/usr/lib/libandroid.so b/ndk/platforms/android-9/arch-arm/usr/lib/libandroid.so index 1b41c6758047e4508cf2f760f71387e2a9a6ef32..2ca0227dee1c7e866589d43856aa665004b5519b 100644 GIT binary patch literal 56544 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 QQ(pM{_&$y%1k~jI7ubtSJpcdz literal 26336 zcmeHwdwf$>w*Nj!`k)O`p(-G13Pn+%Hav?@nl^zxfYPFZ!%P~QKmutKl9Wg3{2C~D z3uS)7h$D}xa7P_L@RE^^g98@?o$-M)siQMKXR0GJh?WK)H$|EDe%E<4JEy6S`#1aZ zSzYV9*V=3Ez4jyfoSd9Cm`g2!ATT9q*%+pvNyt1=C2Eo;F#}76E|U!bXN+_Toq$ZF zlSwHLD5fXM7$Zs|l))tbm5^mRtYNGjM1DyRkyS#cP%0b}k)G<9dnRB9>yyOt$c3qQ z(j2r;CNE`xl=i&@o3G{4zXZPkY6qPJT?G9nNJ+CG{1sFLx)O98lnHtUGy(J#$Od`~ z^aSWZkdjV7@XKHb_#b5XCh#4g{h;}vR*;f@D+}krXDXTChh+I7@V7yCfy{E=J2HP2 z{0>+h3CIEZ8R$LGK@g>-~uBo_B~C(z4rIo}RwEq$LP zd>0F)#@?04Ym${GAE8=akuuA5o ziUK?bRL5Zwe+)8$l0bQ&Ac)e{puwUP`%?ySd<=@xR{Xt%%bUo_Bu?k>CRv^>^KCNE z03QWf3YsV9{Y2(7WNrs{%QDZLGWZqvQ?h&~_y$=fwpx}?$$YoWH-b0FaufIwSteEk zdV#|gkgGYI4f(K)x68a7d^2bZ=uJ=!1p2+4w-5YZpc_CfpnrgV z2igm|2lNJr()*xiLF+*ugVc%E>5ki_&)C73Vf^@!OmlG$^fcE4sInd~ot z-vc~C#v`f2av~cO@N(#B4Uqjp;Df-lFA(;r?6<4%V=DX`;5L+>AeVndrPpZCA51oy zm*jsKu#%`f<5W0bh39d2Bt;d_Cnao7)hCvd7<-xgpqhYtYH;_P1m zp3CX~3A}*AS{=?|95w*EID8lIa$qpAfAb*Ja(F55YG9@R8-O=(_;KK^z+hteV-OzZ z@O!{JIQ$jxqa4n_Cb@^hU;Ovh9U*Pob z0t@Dtzb@dbfR%XblQF&=&H^6I;X8rH11szK$G}RWHtqqwle2#g*bFS~{VD8Km3fHSeb7(V4@5IR^nF;N{%_!#g8&b}RZ2Zwur4{|sU2c{P|yd3x~4(|j0gu@>K|C__t;)C(ZnX&Ph z2t16#Wx!d$*hbOj6t)_8G>3Ns-wd27>;C|JCvchEpML-=iDEKjAg-67r)wBmKVyKE zMEXMDgU~CVcMDYddf-=}$48V{eyd9VI~D#La8i-9Us3yYG*EJ)`qF`~;`Fzx^aa49 zIlWJ%-=)IO0S~Q|u7R^~WfTUsp}ZY+QGd^=>{IAaBqwT50q{GpCo{7DkxIW2_!H<; zW&Kks{oBA7IDLmoe+@S7i=2KuZRB#I`ip^u;+X#`m3}?&08am?O5di!;>`!n|E*Ul zwNd{V`-uwwOoflC@TV#~oSevs#3KB;l55}nD*amEVbIgGr1(Cl(!T^e8v3EK{w?4; zIeZ5A9$*9XG@sIjV1Eau>l5-f0$54pIv;o|^ktAqKUbx9sPHD>4`GifF52$`zPUuY zH$ml}R@uL(!vCYf*;tqxQC^uZCR(U+qV_cbZ{_q)sq~)#?|?oHwp4$*a<~^UV->(p za^?Lh{qKMea{4ylRu2CQ_!uy?h5UDOr+gk+Rr=k)$Dmi@e^{meEAUI4 zzC)!SjEVRA-J6uZ&N*O78>ykkhYI>30KnK(B`{ipNovJ_39ZdQ3@C zuOB8?E@H+es&JkPPX{*7l0F~Ezg4B*1-t-yrT*Wk^ig03r@xvOnw+TrbAgvbuY4Z( zfDZzr$zpqduCjjt_#*VmczmeRXIzW@Z#I>c%8v(D66Lv6xQWAA&_A!j5#YJ-r_`5D zA8c|Wf5U-wl~P6qOJ_F&>wB@Dc^D4K;?_k#Z?e4M_V6&&%YV1Cb z%RaRt;6r_Rg+}uV*_OJhm`^aqx{n@EBWByG9c9ycvt5b2O-97#dCcV{6}eWP9nGD zb9RMwvRI!nH@~XN;rGw-*d1n7D;N7b)y1|IHdVMW2+LGiwKWMcF}i`?8H8b5B|^L3 zV|8Lg+zyss;Hg>cT2kw?1zesQYn8`~F^tbc7-v;gCCaTylv`@6SyGD#Cn!+hsjUh4 z5>+tA=W^5p#5N=-H_uaB<-}ZcIBF7T3mr9nS0Its636OA9-9vfq)(4#+g7-i^j9Cs z`DeQ9_Jq};WWTx!`?7l-K0hLvpvnrd0~M~iM4^$CrJkB42}<7MqNy=&wKq{oNjclK z#2HW*#j;2+a+KS5d~yW1*))n$4_OK-{c4c9KLy2&uSg*9sGty zds2zA6UT2##wl3kah}a(*q@A(%N_oCwnc6Sb_Uuf%<4Mq4!0xFXIj=cRS(z zC5^92Q*K*1KT+m_KAC;Z`r4p*et)eG1EZ=&+HzHy;?6Y7wv-Mx301C|ges4_ze3O? zEEBgws;Zjl^5b~5I$;YXovX^`jt#H%{)xHj=Em$Oo@GWOw~Ut3ndLi*Ea+3D{~G#^ zL#+0`BNEf~J2o*BF$QStl>Tdvjai>2f1iRhI*AHS{#x44{ny9Ml|D5} z!zyi-w3SNRBQ`#9*No*WpPk}X%WwHp?sZgQwiUU|#tC*0?dUkO*H#70Wh=y^ZSQ9T zXP65^`E36!W_hskd)+p2RaOFT>NZK!z8ptGx+>s4g(h>2FREGWF;1f6rnrNO)@D~9 zUvx#lAFsKSxO@e``NRd1+hG&0MPjv1Eq5$7A#i--p|Min(N4Z!y*0RM_!@YVSdgcRgW+AR1P`B_RXBzxHa1Ryb+u=O z!@9^;wQMC$w_GvG@2}isrQBkVk1xh|Fjt--)n2!8;$mDp_?^}j;-talT0e$`6GYv- zdwVbPVm&j*$Fw(EMRtFG?g}QD#Z9Z%Ti>V~C-9EUHO7?t0`&|mA^Q5XnkTgd5Xqd7T=t>;!c}iEG~vH zu1C{)RdjVNPFAS{cARmloTVOIdWsjkaiy>saB5XaTi{zu@@jM0)O@LmGKaM-yi*Z(9-WG>CS*gWAUZvyWVf0*}4Kg@jc4>OO^JIzdx1qU;ri`G7jd(SZhlC& zo~&-q65Kh%K{cVHJSs4!rpjSO1aOnaxz9_rtf>*MwYjjqbOtob9PmB8{cb@@M15#R>;q3a!A653AE*FJHI()VvGfvsw?$|a_Os)XO^S^2~2h%52^>Tm?^!!1tFO6lr{o3Im=t5&PJ zS#d=Y)smnqy=6Q;TvNvdEU%w{VesUpiDeR1q=Zbevnq344y2shyCS51$hjEj`&@S1 znoW4G*QoLg>zNMec8}T%CK&Z7zD~4Vx)to7;qX*D#2avN1*JQO`8D=3k3TLPQ!8qH zi)~d7V+k&S#ap9&vnQfKxL1n>FsU483vu=<VK+aR)wxUn`WV=XJ`OwAX>=b5#5c9FSeMOmJ8 zsb|qrG?wL8;BKSGN4B`yD|EPRs)L%OHySwuidU={?x=X&wc=e2e%Viv3rCPvBAqRuiycRlaWu*` z#q97&W5ZDux1FRmiyB-ga7gmkdxnYI75h4zjEXIGG>JB7tQ?2WSK~?Gk7gU)eJZD0 zJbc9ax)e9*USnJn(8*G6;Hm_!?Jhsv8v-o0d^>8szv~ISabnNPcN5CB z97RNow^FrYfLomiRBYV%C1ac@byc=CPEi}jCWzt=gH-5PY^!w#Vo~ayBx-kRV>*t+ z)hJ%}iVLt5H%{Usu5w1}NGeOFI8c|w4d=IXOTBGPtH3u_xXbCOp_7U#24?eQe<|%% zyuGe1+c!D^dpV&(r&k-CT zj_=P85y$u3hl%6+=-(2@_qIog7vLFX;&{gGMdEAldkW%s(D^iRJS-k2z823a6JLkl z@ep5+XS0bvfbWlqH{tng;u{$|OMEk)WhVYJ{Dy`2gZK>$@vZo+2l0m(yF~n9e0_}X zpRaxd--8q1fp3$E@5J}u#CPF)W#TP(hJg5^cs7UlV|Yf4_~UpMhxl$hgF$=`V`GT_ z63-$Ne-giWA-*5qqZ2=XXa0#F#4`iL58)XK;vqbHM*P=!_J;Uj#!89*2G8yg|1F-= zC;mKs`$YT{V+)DDglBVz{~phH5&r{YPU0`)8EN9L;#m{or}0}E;(ugp74a~BgG2lc z#)8D(#53;1|AJ?7h`){TC;kq`pZL2Nf8y_B{E7b!<4?RD<4^n_7=PktF#g2*>z27!<^h>chn)uF zSx6k?Ig>cXvy?c-vy3>#a~^Sw=X~P35ntka5HI+->J!9^_&Lmz_VH(Q?T??iqW!`4 z)X0CI3Ea%^!-5At(!9F)qrkM{sf` zC+j&`$H|wvVr~AClRx9+k2(2$PJWYMWD{*049=H&M| z`Atqf&B-rv@=;Dc%*h8h`3X*L;pA*+oFy)nMHxp)CP)Vv+XEB6&q8&YC|Ie5`tVY34g;PIL^NnEaiGJL%+nI693wyIu zKMKA2Cg}^4bBl9>DfNxH&ZG-M(knyt6K6X$IbXGD+L^&o={+XZ^)gCE|HY1bTYI7} zcO+T#hMwrF9c+}&l2lnx$;9@&jP`iN_GoVz^7h})Y9cyKa;h*=*Um<2+BG9tyLMzx z^!W~Itq$e)cjzh^YN0-i|0I&1IZJ1`!t&F?G3doJ9b;ENbmS%{dRX+lYjxq48H0)k zmDClkDHJRQXSi$Ca)af!Gxk;rhB3?2W=Umsc4WbRzq74ti_vJ=KI7Qg$l7N{UCQoL-ZeB7~<$3~WUG)~<{b_t)Fa zTf43l^%-oTYmvFwMYhx7=Q{Xlacv^}CG&1Gjc7<~5WQBGG;A}8xs@$uF{do|SZ-^9 zGyO=hb7yE>Q*+Z!Q&Jc|_lrCe#E&5(2ZJY@UhB=Y zFRWRUzGkOMi*_sxv$0FV1t?#P^2KrG7mDS7#FeiQ%a?~uYf9wu#VB7K*1Ax?OY`iy z`sVt^a~j=~DcbPEDR+b)1!YF`sC_X0PC^^>gC>SG_38Ce?PF1TY}iy^0xX0_K0Ef= z0(dHR-5*-Fsd*FSy%BmZbaK;cqWqtsr$ddo(Vstc+x;migaD?^)h z4b5U|W9AyFd1sJDsI=j9XjVhxxg?BmO8B0JoD>}*I*8HCKOlM-5S}M`kVacC`hL9q zlyk_D*PLwZt>IG}PjCFCDH~DGJU+~_JBy7=J-$18vq|?sswK;U-A#%|LYf9I&m^9&eXs4x3>l$(- z-NnY{h99W^S$%Rut4oS#wJoMA!av7K(?_%^BO=;CDPcBlF4{0R{43L(@Z+YEaB@Ts zOFb-8!VlM9g;|2RIqq)Q+#S}|>+4%E(wX&#j}+9Git@br^+#x?l(-s0jhjMUnTVAT z-nMDnkyD#aZ)(9@cyrT;(9r8CGB>o-oN0EQ3h6LsT1?5|tC~lLT1?x-=w!4{Zw_@0 zKe67N8lKy146!^alhoc5&F)ra5$$0Stl_6ao0=M%MusMa9x_djyc>jm?DWWAg0D86 z>dpO=ocmgE9oBDp-R)Szw}cL19;I(=F;9;i4{oZvE!0>y7I|qWiZ^aUUTg3aVpbB? zG^95SjttUiB7;)UifoK+68LD$qU3Ri@pC5j#p6MilX;wF>mq`VX2v5ytY{5JI-Bfs zwIq=)Gqe+JYzmqhO2}uD>~l1H>c}_w9F3?xXR2+JJj{tO{Tz&|;zbWHdU$cPopjzG zN?&trNV6sl_{VJ}kWHd|A4Z&wogAihKRBXAEm~?hYSGHIXi-Z#Y8em~?uO00a%q`SK9HOMDL zIisx+^C7(%<(f&C`gTckL1=n&ZfLs+F~d4jMl^!Y-zzZR2mNuhWzb8%I6H`K0MTbo zu*o~)1V~et<}Iiz@zU929pqE8%+`2kOb4CV2u(d?P_Ujww2b(PFV=#yW>5pe$|Qc` z3n2q`GM+BuwL$NU7eHyNG`^Bm1wL3FPg}JP@+nak{N5S)pcmG9X9xkvpmp^^L@SKM ziW*k1R>T{b5YZz?FXyo1LL=JVAVdZscMx)gm4pWfLL?VCxpEFWZsKh6VPlH3p&UBX z^hAp;(YdH6+R!cW`~FRzzp0jt)?qjy9R7sP4WzGul+kLyi6Zz3%QB3lQ`Lb_l(P{| zWa4R!9iQ$*oIoc)%!Rmsf}j&1w$wXAYY8rWN91hTf@P8&*)Wizd%@l4F1}v-=}DoY zYXU1GPse#5(@{Q%vIWa3y0S0^C*2j-uUn@1Mmr*VQu8eeQ2Z<9UhXG9 zm3p73t^MRT^^^Z{Kl!PM7CU~zE#whzbZb9-K~vFXWOK##G%nMAqfy08%2V1c#jJ4| z#f-P@8!xg+5p9&R@v(~cE5#{3Pl{1|o)n+>yqRKO7n3x|+y5 zD?DnjbVpBijN zvgBEGSt%pCqkrkVvZ%hWlFDoIEW$(G(KkA;2x)gtsGNnrCUf!|KWAesnjI{=JG!@1 zX!k_Yb;91B=nJ^cNNMcmk)#QoqbunuZECAk)Elm3+oEIqx(Atvf_|jTnP<;uyG5Pj|GYb1%+ZDQJC4u~gG+xxX|A4~X8` z@nP^?3ZijYD98UNB2O#mj*=veU8R`UC|}c`5_w81%POcA_HUoT#_T;VY`+4wDXl_+ zJWZcGKh6O|EG#=Ii*1`=*-*U~*ZcKiU9<+fqdA>)YDbiErEBC!>m!)OndogE#+Jrw zq$N9)CysD-=WUi;%N3!ga3!9$PZ-r5HFPFhGC~yN%=WZhV=L2lF0It>*jIVQ_Oq3P zc8#@_h6Y~H=?5QdkxwA&!6#wdyQ67{B{`@A%#nH)Qf%ypd%cN?VG#bl{(WP{j={nT^{S!^WEfZBsy$+>I`PJ--U zmyS8n$FI+`F}ioVqnFML&Y7kG?Z+-A8-!biic!(DNhfBCIo29{&H1vcxGMB*a(T575pbt$GX1$7jy#L&C06m9#HU4Hzb?~k)$#?nJL2HO(+g3Ykf z6>u8pHxmvYDmCPn&Y4qYF1MDIo6GXc&DQ+V(mD58XU~~!Er4jsFDR*CNGTy8pc5QiOcYJX6~`-6w&d>W(6 z>2d@vN8oYKuMtOaFPaIa-H=4&@Um={g|imEH3d@ znV*#TA7%cY%s-a-d6}od50x{>e2mN|gVXy1?*zx=zv9c|t_9PBh7+%p-mgeldA%96 zkrKU^k=m{#dZvrsw>Y#?dJmqG&+|)&!)5yJ81OOE0i=S6&zOA=TjFus4aS^l`9@@j zFU(@XO%Rjv%V!x@Ol8SwDfy|w08N@!FAUaY3Rel&Xom{JHP>ocj?W`L6rbaF;`i_Y z+ai{OLOFPI6p8lLHMVM370bczQk)|6udZe}HJ*SYXGu+M4plsUh5XW=9Q?kEO27_} z*^9{MkqQNTl3V;@*5_J;cV_un4xX<^?I_}P2N*oz4_?uPzf%2po}cB=Zx*|-8;zu+dL~D)mY26X+#zLfZOo?o0j$=BDd1OcH zk%-o#l4w0qY5)xYksYmjBH9NC6Olg}zfzE5NBaR0?FVYRM&yxiT3gCm*{n1UdE}20 z9+&U6qdko%JXlnTe-u0NMKl34AMckV+9z5_e-u6KOC*bJo`ZToxtyKi?;**KUcVjp z|3?r;F)97s4@7&5*z`&WAlgTir1-<*+~WJ*$&U6LkrX3vY7?bCG6mP?h#zsj>6KJj|Z6;k>mGu8e)OP<10@G73 diff --git a/ndk/platforms/android-9/samples/native-activity/jni/main.c b/ndk/platforms/android-9/samples/native-activity/jni/main.c index 9d83f041f..378fd621f 100644 --- a/ndk/platforms/android-9/samples/native-activity/jni/main.c +++ b/ndk/platforms/android-9/samples/native-activity/jni/main.c @@ -17,9 +17,10 @@ //BEGIN_INCLUDE(all) #include - #include +#include + #include #include "glutils.h" @@ -39,6 +40,10 @@ struct saved_state { struct engine { struct android_app* app; + ASensorManager* sensorManager; + const ASensor* accelerometerSensor; + ASensorEventQueue* sensorEventQueue; + int animating; EGLDisplay display; EGLSurface surface; @@ -151,20 +156,40 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) { struct engine* engine = (struct engine*)app->userData; switch (cmd) { case APP_CMD_SAVE_STATE: + // The system has asked us to save our current state. Do so. engine->app->savedState = malloc(sizeof(struct saved_state)); *((struct saved_state*)engine->app->savedState) = engine->state; engine->app->savedStateSize = sizeof(struct saved_state); break; case APP_CMD_INIT_WINDOW: + // The window is being shown, get it ready. if (engine->app->window != NULL) { engine_init_display(engine); engine_draw_frame(engine); } break; case APP_CMD_TERM_WINDOW: + // The window is being hidden or closed, clean it up. engine_term_display(engine); break; + case APP_CMD_GAINED_FOCUS: + // When our app gains focus, we start monitoring the accelerometer. + if (engine->accelerometerSensor != NULL) { + ASensorEventQueue_enableSensor(engine->sensorEventQueue, + engine->accelerometerSensor); + // We'd like to get 60 events per second (in us). + ASensorEventQueue_setEventRate(engine->sensorEventQueue, + engine->accelerometerSensor, (1000L/60)*1000); + } + break; case APP_CMD_LOST_FOCUS: + // When our app loses focus, we stop monitoring the accelerometer. + // This is to avoid consuming battery while not being used. + if (engine->accelerometerSensor != NULL) { + ASensorEventQueue_disableSensor(engine->sensorEventQueue, + engine->accelerometerSensor); + } + // Also stop animating. engine->animating = 0; engine_draw_frame(engine); break; @@ -188,6 +213,13 @@ void android_main(struct android_app* state) { state->onInputEvent = engine_handle_input; engine.app = state; + // Prepare to monitor accelerometer + engine.sensorManager = ASensorManager_getInstance(); + engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, + ASENSOR_TYPE_ACCELEROMETER); + engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, + state->looper, LOOPER_ID_USER, NULL, NULL); + if (state->savedState != NULL) { // We are starting with a previous saved state; restore from it. engine.state = *(struct saved_state*)state->savedState; @@ -197,19 +229,32 @@ void android_main(struct android_app* state) { while (1) { // Read all pending events. - int fd; + int ident; int events; struct android_poll_source* source; // If not animating, we will block forever waiting for events. // If animating, we loop until all events are read, then continue // to draw the next frame of animation. - while ((fd=ALooper_pollAll(engine.animating ? 0 : -1, &events, + while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, &events, (void**)&source)) >= 0) { // Process this event. if (source != NULL) { - source->process(state); + source->process(state, source); + } + + // If a sensor has data, process it now. + if (ident == LOOPER_ID_USER) { + if (engine.accelerometerSensor != NULL) { + ASensorEvent event; + while (ASensorEventQueue_getEvents(engine.sensorEventQueue, + &event, 1) > 0) { + LOGI("accelerometer: x=%f y=%f z=%f", + event.acceleration.x, event.acceleration.y, + event.acceleration.z); + } + } } // Check if we are exiting. diff --git a/ndk/platforms/android-9/samples/native-plasma/jni/plasma.c b/ndk/platforms/android-9/samples/native-plasma/jni/plasma.c index 6d725ae89..c364f1813 100644 --- a/ndk/platforms/android-9/samples/native-plasma/jni/plasma.c +++ b/ndk/platforms/android-9/samples/native-plasma/jni/plasma.c @@ -469,19 +469,19 @@ void android_main(struct android_app* state) { while (1) { // Read all pending events. - int fd; + int ident; int events; struct android_poll_source* source; // If not animating, we will block forever waiting for events. // If animating, we loop until all events are read, then continue // to draw the next frame of animation. - while ((fd=ALooper_pollAll(engine.animating ? 0 : -1, &events, + while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, &events, (void**)&source)) >= 0) { // Process this event. if (source != NULL) { - source->process(state); + source->process(state, source); } // Check if we are exiting. 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 index 05c638ede..7888f7dc2 100644 --- a/ndk/sources/android/native_app_glue/android_native_app_glue.c +++ b/ndk/sources/android/native_app_glue/android_native_app_glue.c @@ -89,7 +89,8 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { if (android_app->inputQueue != NULL) { LOGI("Attaching input queue to looper"); AInputQueue_attachLooper(android_app->inputQueue, - android_app->looper, NULL, &android_app->inputPollSource); + android_app->looper, LOOPER_ID_INPUT, NULL, + &android_app->inputPollSource); } pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); @@ -178,7 +179,7 @@ static void android_app_destroy(struct android_app* android_app) { // Can't touch android_app object after this. } -static void process_input(struct android_app* app) { +static void process_input(struct android_app* app, struct android_poll_source* source) { AInputEvent* event = NULL; if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { LOGI("New input event: type=%d\n", AInputEvent_getType(event)); @@ -193,7 +194,7 @@ static void process_input(struct android_app* app) { } } -static void process_cmd(struct android_app* app) { +static void process_cmd(struct android_app* app, struct android_poll_source* source) { int8_t cmd = android_app_read_cmd(app); android_app_pre_exec_cmd(app, cmd); if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); @@ -216,7 +217,8 @@ static void* android_app_entry(void* param) { android_app->inputPollSource.process = process_input; ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); - ALooper_addFd(looper, android_app->msgread, POLLIN, NULL, &android_app->cmdPollSource); + ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, POLLIN, NULL, + &android_app->cmdPollSource); android_app->looper = looper; pthread_mutex_lock(&android_app->mutex); diff --git a/ndk/sources/android/native_app_glue/android_native_app_glue.h b/ndk/sources/android/native_app_glue/android_native_app_glue.h index e60f1c079..321299cac 100644 --- a/ndk/sources/android/native_app_glue/android_native_app_glue.h +++ b/ndk/sources/android/native_app_glue/android_native_app_glue.h @@ -59,25 +59,26 @@ extern "C" * * - 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_INPUT, respectively. + * Each of these correspond to an ALooper identifier returned by + * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT, + * respectively. * - * Your application can use the same ALooper to listen to additionnal - * file-descriptors. + * Your application can use the same ALooper to listen to additional + * file-descriptors. They can either be callback based, or with return + * identifiers starting with LOOPER_ID_USER. * - * 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. + * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event, + * the returned data will point to an android_poll_source structure. You + * can call the process() function on it, and fill in android_app->onAppCmd + * and android_app->onInputEvent to be called for your own processing + * of the event. * - * XXX: MAKE THIS STUFF MORE CLEAR !! - * - * 5/ Whenever you receive a LOOPER_ID_INPUT event from the ALooper, you - * should read one event from the AInputQueue with AInputQueue_getEvent(). + * Alternatively, you can call the low-level functions to read and process + * the data directly... look at the process_cmd() and process_input() + * implementations in the glue to see how to do this. * * See the sample named "native-activity" that comes with the NDK with a - * full usage example. - * + * full usage example. Also look at the JavaDoc of NativeActivity. */ struct android_app; @@ -91,12 +92,12 @@ struct android_poll_source { // LOOPER_ID_INPUT. int32_t id; - // The android_app this fd is associated with. + // The android_app this ident is associated with. struct android_app* app; // Function to call to perform the standard processing of data from // this source. - void (*process)(struct android_app* app); + void (*process)(struct android_app* app, struct android_poll_source* source); }; /** @@ -185,7 +186,9 @@ struct android_app { enum { /** - * Looper data ID of commands coming from the app's main thread. + * Looper data ID of commands coming from the app's main thread, which + * is returned as an identifier from ALooper_pollOnce(). The data for this + * identifier is a pointer to an android_poll_source structure. * These can be retrieved and processed with android_app_read_cmd() * and android_app_exec_cmd(). */ @@ -193,10 +196,17 @@ enum { /** * Looper data ID of events coming from the AInputQueue of the - * application's window. These can be read via the inputQueue + * application's window, which is returned as an identifier from + * ALooper_pollOnce(). The data for this identifier is a pointer to an + * android_poll_source structure. These can be read via the inputQueue * object of android_app. */ - LOOPER_ID_INPUT = 2 + LOOPER_ID_INPUT = 2, + + /** + * Start of user-defined ALooper identifiers. + */ + LOOPER_ID_USER = 3, }; enum {