android GPS HAL 回调函数实现

实现自己的GPS的HAL层,要实现gps.c文件,(按照Android系统的调用)参考 http://blog.chinaunix.net/uid-25570748-id-184090.html分析的很好。
 
   

const struct hw_module_t HAL_MODULE_INFO_SYM = {
     . tag = HARDWARE_MODULE_TAG ,
     . version_major = 1 ,
     . version_minor = 0 ,
     . id = GPS_HARDWARE_MODULE_ID ,
     . name = "Goldfish GPS Module" ,
     . author = "The Android Open Source Project" ,
     . methods = & gps_module_methods ,
};

 
   

static struct hw_module_methods_t gps_module_methods = {
     . open = open_gps
};

 
   

static int o pen_gps ( const struct hw_module_t * module , char const * name ,
         struct hw_device_t ** device )
{
     struct gps_device_t * dev = malloc ( sizeof ( struct gps_device_t ));
    memset ( dev , 0 , sizeof (* dev ));
    D ( "%s: called\n" , __FUNCTION__ );
    dev -> common . tag = HARDWARE_DEVICE_TAG ;
    dev -> common . version = 0 ;
    dev -> common . module = ( struct hw_module_t *) module ;
//    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
    dev->get_gps_interface = gps__get_gps_interface ;

    *device = ( struct hw_device_t *) dev ;
     return 0 ;
}

 
   

const GpsInterface * gps__get_gps_interface ( struct gps_device_t * dev )
{
    D ( "%s: called\n" , __FUNCTION__ );
     return & sepGpsInterface ;
}

 
   

static const GpsInterface   sepGpsInterface = {
     sizeof ( GpsInterface ),
    sep_gps_init ,
    sep_gps_start ,
    sep_gps_stop ,
    sep_gps_cleanup ,
    sep_gps_inject_time ,
    sep_gps_inject_location ,
    sep_gps_delete_aiding_data ,
    sep_gps_set_position_mode ,
    sep_gps_get_extension ,
};

这里的GpsInterface定义如下,在hardware/libhardware/include/hardware/gps.h文件中
 
     

/** Represents the standard GPS interface. */
typedef struct {
size_t size;
int (*init)( GpsCallbacks* callbacks );
int (*start)( void );
int (*stop)( void );
void (*cleanup)( void );
int (*inject_time)(GpsUtcTime time, int64_t timeReference, int uncertainty);
int (*inject_location)(double latitude, double longitude, float accuracy);
void (*delete_aiding_data)(GpsAidingData flags);
int (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
const void* (*get_extension)(const char* name);
} GpsInterface;


 
     

/** GPS callback structure. */ typedef struct { /** set to sizeof(GpsCallbacks) */ size_t size; gps_location_callback location_cb; gps_status_callback status_cb; gps_sv_status_callback sv_status_cb; gps_nmea_callback nmea_cb; gps_set_capabilities set_capabilities_cb; gps_acquire_wakelock acquire_wakelock_cb; gps_release_wakelock release_wakelock_cb; gps_create_thread create_thread_cb; } GpsCallbacks;


比如说GpsInterface里面init函数,需要一个参数,callbacks,没有发现哪里有对回调函数的定义。有读了一遍别人的博客的分析 http://blog.chinaunix.net/uid-25570748-id-184090.html
GPS服务启动的过程中,在JNI层会去初始化GPS
com_android_server_location_GpsLocationProvider.cpp文件中的ini函数
 
     

static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) { const GpsInterface* interface = GetGpsInterface(env, obj); if (!interface) return false; if (!sGpsDebugInterface) sGpsDebugInterface = (const GpsDebugInterface*)interface->get_extension(GPS_DEBUG_INTERFACE); return true; }

调用了GetGpsInterface去获取接口并初始化GPS

 
     

static const GpsInterface* GetGpsInterface(JNIEnv* env, jobject obj) { // this must be set before calling into the HAL library if (!mCallbacksObj) mCallbacksObj = env->NewGlobalRef(obj); if (!sGpsInterface) { sGpsInterface = get_gps_interface(); if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) { sGpsInterface = NULL; return NULL; } } return sGpsInterface; }

GetGpsInterface里面也去调用了get_gps_interface(),而这个函数最早的地方便是isSupported()的这个函数。在获取了这个接口之后,使用sGpsInterface->init函数进行了初始化。原来是在这里注册了回调函数。
sGpsCallbacks是个全局变量,在com_android_server_location_GpsLocationProvider.cpp文件中
 
    

GpsCallbacks   sGpsCallbacks  = {
     sizeof ( GpsCallbacks ),
     location_callback ,
    status_callback ,
    sv_status_callback ,
    nmea_callback ,
    set_capabilities_callback ,
    acquire_wakelock_callback ,
    release_wakelock_callback ,
    create_thread_callback ,
};
然后,也有各个回调函数的实现
 
     

static void location_callback ( GpsLocation * location )
{
     JNIEnv * env = AndroidRuntime :: getJNIEnv ();
    env -> CallVoidMethod ( mCallbacksObj , method_reportLocation , location -> flags ,
            (jdouble ) location -> latitude , ( jdouble ) location -> longitude ,
            (jdouble ) location -> altitude ,
            (jfloat ) location -> speed , ( jfloat ) location -> bearing ,
            (jfloat ) location -> accuracy , ( jlong ) location -> timestamp );
    checkAndClearExceptionFromCallback ( env , __FUNCTION__ );
}

 
     

static void status_callback ( GpsStatus * status )
{
     JNIEnv * env = AndroidRuntime :: getJNIEnv ();
    env -> CallVoidMethod ( mCallbacksObj , method_reportStatus , status -> status );
    checkAndClearExceptionFromCallback ( env , __FUNCTION__ );
}

 
     

static void sv_status_callback ( GpsSvStatus * sv_status )
{
     JNIEnv * env = AndroidRuntime :: getJNIEnv ();
    memcpy (& sGpsSvStatus , sv_status , sizeof ( sGpsSvStatus ));
    env -> CallVoidMethod ( mCallbacksObj , method_reportSvStatus );
    checkAndClearExceptionFromCallback ( env , __FUNCTION__ );
}

 
     

static void nmea_callback ( GpsUtcTime timestamp , const char * nmea , int length )
{
     JNIEnv * env = AndroidRuntime :: getJNIEnv ();
     // The Java code will call back to read these values
    // We do this to avoid creating unnecessary String objects
    sNmeaString = nmea;
    sNmeaStringLength = length;
    env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
}

 
     

static void set_capabilities_callback ( uint32_t capabilities )
{
    LOGD ( "set_capabilities_callback: %ld\n" , capabilities );
     JNIEnv * env = AndroidRuntime :: getJNIEnv ();
    env -> CallVoidMethod ( mCallbacksObj , method_setEngineCapabilities , capabilities );
    checkAndClearExceptionFromCallback ( env , __FUNCTION__ );
}

 
     

static void acquire_wakelock_callback ()
{
    acquire_wake_lock ( PARTIAL_WAKE_LOCK , WAKE_LOCK_NAME );
}

static void release_wakelock_callback ()
{
    release_wake_lock ( WAKE_LOCK_NAME );
}

static pthread_t create_thread_callback ( const char * name , void (* start )( void *), void * arg )
{
     return ( pthread_t ) AndroidRuntime :: createJavaThread ( name , start , arg );
}







你可能感兴趣的:(Android,GPS)