android2.3 gps 调用流程以及与android2.2 gps的一些区别

     本篇从jni层往下看,讲下应用程序大概的调用流程,jni往上的前辈们已经说得十分清楚了。

 

gps jni路径 /framework/base/services/jni/com_android_server_location_GpsLocationProvider.cpp
static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
    {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
    {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported},
    {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init},
    {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup},
    {"native_set_position_mode", "(IIIII)Z", (void*)android_location_GpsLocationProvider_set_position_mode},
    {"native_start", "()Z", (void*)android_location_GpsLocationProvider_start},
    {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop},
    {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data},
    {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status},
    {"native_read_nmea", "([BI)I", (void*)android_location_GpsLocationProvider_read_nmea},
    {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time},
    {"native_inject_location", "(DDF)V", (void*)android_location_GpsLocationProvider_inject_location},
    {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra},
    {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data},
    {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open},
    {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed},
    {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed},
    {"native_agps_set_id","(ILjava/lang/String;)V",(void*)android_location_GpsLocationProvider_agps_set_id},
    {"native_agps_set_ref_location_cellid","(IIIII)V",(void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid},
    {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server},
    {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response},
    {"native_agps_ni_message", "([BI)V", (void *)android_location_GpsLocationProvider_agps_send_ni_message},
    {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state},
    {"native_update_network_state", "(ZIZLjava/lang/String;)V", (void*)android_location_GpsLocationProvider_update_network_state },
};
其中就讲加粗的4个部分:
native_is_supported
native_init
是系统在服务层自动调用的,也就是说系统在启动后,就会调用上面两个,看看本机是否支持gps功能。
native_start
native_stop
是应用程序调用的,当应用程序启动时会调用 native_start,关闭时会调用 native_stop
先讲 native_is_supported 它会调用android_location_GpsLocationProvider_is_supported
static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
    LOGE("in  android_location_GpsLocationProvider_is_supported-------->");
    return (sGpsInterface != NULL || get_gps_interface() != NULL);
}
 注意在这里2.2和2.3的就有点区别了,2.2时get_gps_interface() 会直接调用到硬件抽象层的 gps.cppgps_get_interface()
而在2.3中却不是了,都没gps.cpp这个文件了,2.3中它调用的是它本文件中的get_gps_interface()
                                    (com_android_server_location_GpsLocationProvider.cpp中
static const GpsInterface* get_gps_interface() {
    int err;
    hw_module_t* module;
    const GpsInterface* interface = NULL;
    err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    if (err == 0) {
        hw_device_t* device;
        err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
        if (err == 0) {
            gps_device_t* gps_device = (gps_device_t *)device;
            interface = gps_device->get_gps_interface(gps_device);
        }
    }
    return interface;
}
hw_get_moduleopen(module, GPS_HARDWARE_MODULE_ID, &device);是干什么呢? 看下gps_qemu.c最后几行:
static struct hw_module_methods_t gps_module_methods = {
    .open = open_gps
};
const struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .version_major = 1,
    .version_minor = 0,
    .id = GPS_HARDWARE_MODULE_ID,     // 这个id很重要,jni层就通过这个id找到这个module
    .name = "Goldfish GPS Module",
    .author = "The Android Open Source Project",
    .methods = &gps_module_methods,
};
这下明白了, 先得到模块,打开模块,这和2.2也不一样了,在看下open_gps

static int open_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));

    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;
}

再往下看下gps__get_gps_interface

const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
{
    D("---------return &qemuGpsInterface; -----------");//add bu liu
    return &qemuGpsInterface;
}

static const GpsInterface  qemuGpsInterface = {
    sizeof(GpsInterface),
    qemu_gps_init,
    qemu_gps_start,
    qemu_gps_stop,
    qemu_gps_cleanup,
    qemu_gps_inject_time,
    qemu_gps_inject_location,
    qemu_gps_delete_aiding_data,
    qemu_gps_set_position_mode,
    qemu_gps_get_extension,
};

ok,现在知道在open_gps中,把gps接口传上去了。

接下来系统会调用native_init:

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;
}

其中好像没有调用到硬件抽象层的 init 接口? 没关系玩下看下GetGpsInterface(env, obj);

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)   //会调用qemu_gps_init,
 {
            sGpsInterface = NULL;
            return NULL;
        }
    }
    return sGpsInterface;
}

这里面有,他会掉下去qemu_gps_init,

应用程序启动时会调用 native_start,关闭时会调用 native_stop
这个流程和上面的差不多,不讲了
咱也是新人,有错的,请留言啊

再看 get_extension:

static const void* qemu_gps_get_extension(const char* name)
{
    // no extensions supported
    return NULL;
}

 

其实他啥也没做,ok  到此为止,系统做的初始化已经完了,服务已经注册,接下来你就可以启动应用程序了。


你可能感兴趣的:(android,struct,Module,jni,interface,extension)