Transferred from: http://qiuzhenqing.blog.edu.cn/2010/576669.html. Author: qiuzhenqing
Currently, Android does not have an application interface class for fmradio. Next, we will analyze an existing implementation case.
Hardware: bcm4329 + cpcap
Requirement: bcm4327 needs to be connected to the RX Antenna
Audio analog out is connected to cpcap
Software:
Fmradio.apk --> JAVA application
Libfmradio_jni.so: Frameworks/base/fmradio/JNI --> JNI
Libfmradioplayer. So: --> hal
Libfmradiostackservice. So: --> hal
Libfmradio. so this is the basic function library for implementing FM. For example, the search platform depends on libblustmth libutils and is related to Bluetooth because bcm4329 is a Bluetooth + WiFi + FM synthesis chip, which shares power with Bluetooth, commands share one HCI.
Libaudio. So
First, in init. RC, you need to start an FM service, which is fmradio and the executable file is fmradioserver.
Service fmradio/system/bin/fmradioserver
Group Bluetooth
Fmradioserver code example:
Int main (INT argc, char ** argv)
{
....
Fmradiostackservice: instantiate (); // start the fmradio. Stack Service
....
}
Fmradiostackservice. cpp
Void fmradiostackservice: instantiate (){
Defaultservicemanager ()-> addservice (
String16 ("fmradio. Stack"), new fmradiostackservice ());
}
Through this fmradiostackservice class, the basic functions of FM are available.
Class fmradiostackservice: Public bnfmradiostackservice, protected thread
{
Public:
Static void instantiate ();
...
Virtual bool powerondevice ();
Virtual bool poweroffdevice ();
Virtual void setfmradioplayerclient (const sp & client );
Virtual bool open ();
Virtual bool getband () const;
Virtual bool setband (radio_band bind );
Virtual bool tune (unsigned int freq );
Virtual bool currentfreq () const;
Virtual bool setaudiomode (audio_mode mode );
Virtual bool getaudiomode () const;
Virtual bool seek (seek_direction direction );
Virtual bool stopseek ();
Virtual bool setvolume (unsigned int vol );
Virtual bool getvolume () const;
Virtual bool setemphasisfilter (emphasis_filter filter );
Virtual bool getemphasisfilter () const;
Virtual bool setmute (mute_mode mode );
Virtual bool ismute () const;
Virtual bool enableaudiotarget (audio_target Val); // shocould be called after set band;
Virtual bool disableaudiotarget (audio_target Val );
Virtual bool getrssilevel ();
Virtual int getchipsetid ();
Virtual bool close ();
Static void fm_int_handler (fmradio_msgs_t, Int, Int, char *);
PRIVATE:
SP m_client;
....
};
Fmradiostackservice inherits bnfmradiostackservice, bnfmradiostackservice inherits bbinder and ifmradiostackservice, and implements ontransact (). If the entire fmradio is regarded as the Client/Server mode, the server is complete. Here, a private member variable m_client is strange. It is actually used to go up to the running y state and assigned values through virtual void setfmradioplayerclient (const sp & client.
According to the Binder Mechanism, we know that there will be a bpfmradiostackservice, which inherits from bbinder and ifmradiostackservice, implements ifmradiostackservice through remote ()-> transact (), and provides various fmradio functions to the upper layer of the client, of course, remote ()-> transact () calls the real underlying service through bnfmradiostackservice.
Using JNI gmethods
Static jninativemethod gmethods [] = {
{"Powerondevice", "() Z", (void *) fmradio_poweron },
{"Poweroffdevice", "() Z", (void *) fmradio_poweroff },
{"Open", "() Z", (void *) fmradio_open },
{"Getband", "() Z", (void *) fmradio_getband },
{"Setband", "(I) Z", (void *) fmradio_setband },
{"Tune", "(I) Z", (void *) fmradio_tune },
{"Currentfreq", "() Z", (void *) fmradio_currentfreq },
{"Setaudiomode", "(I) Z", (void *) fmradio_setaudiomode },
{"Getaudiomode", "() Z", (void *) fmradio_getaudiomode },
{"Seek", "(I) Z", (void *) fmradio_seek },
{"Stopseek", "() Z", (void *) fmradio_stopseek },
{"Setvolume", "(I) Z", (void *) fmradio_setvolume },
{"Getvolume", "() Z", (void *) fmradio_getvolume },
{"Setemphasisfilter", "(I) Z", (void *) fmradio_setemphasisfilter },
{"Getemphasisfilter", "() Z", (void *) fmradio_getemphasisfilter },
{"Setmute", "(I) Z", (void *) fmradio_setmute },
{"Ismute", "() Z", (void *) fmradio_ismute },
{"Enableaudiotarget", "(I) Z", (void *) fmradio_enableaudiotarget },
{"Disableaudiotarget", "(I) Z", (void *) fmradio_disableaudiotarget },
{"Close", "() Z", (void *) fmradio_close },
{"Native_setup", "(ljava/lang/object;) V", (void *) fmradio_native_setup },
{"Native_finalize", "() V", (void *) fmradio_native_finalize}
};
Add registernativemethods
If (androidruntime: registernativemethods (ENV, "com/Motorola/fmradio/fmradioplayer", gmethods, nelem (gmethods)> = 0 ){
Result = jni_version_1_4;
}
We provided the FM class com. Motorola. fmradio. fmradioplayer to application developer.
Of course, you also need to write fmradioplayer. cpp to declare these native methods.
The following story should start with native_setup because it is bound to the fmradio. Stack service, so it is placed in the fmradioplayer constructor.
Jniexport void jnicall fmradio_native_setup (jnienv * ENV, jobject OBJ, jobject weak_this)
{
Logi ("in JNI fmradio_native_setup/N ");
SP fmstack = getfmradiostackservice (); // here binder = Sm-> getservice (string16 ("fmradio. Stack "));
...
}
Future application layer content (omitted)