本篇从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.cpp 的gps_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_module 、open(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 到此为止,系统做的初始化已经完了,服务已经注册,接下来你就可以启动应用程序了。