目录
GPS 位置数据源头
GPS 位置数据一定是从gps模块反馈回来的,通过Hal往上callback传出去的。
这个我在跟踪gps数据流程时,一直坚信的原则。 奈何android java,hidl hal,jni, driver各层
反复绕在一起。应该是对代码分层没有理清楚。
代码流程跟踪分析
=====================================================================
\frameworks\base\services\core\jni
com_android_server_location_GnssLocationProvider.cpp // jni 层
static jmethodID method_reportLocation;
struct GnssCallback : public IGnssCallback {
Return<void> gnssLocationCb(
Return<void> GnssCallback::gnssLocationCb(
const ::android::hardware::gnss::V1_0::GnssLocation& location) {
env->CallVoidMethod(mCallbacksObj,
method_reportLocation,
boolToJbool(hasLatLong),
jLocation);
static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
method_reportLocation = env->GetMethodID(clazz, "reportLocation",
"(ZLandroid/location/Location;)V"); / java类名, java 类方法, 往上走
=====================================================================
gps/service/mtkgnss.cpp
GpsCallbacks MtkGnss::sGnssCb = { // 对外对内的 接口连接
.size = sizeof(GpsCallbacks),
.location_cb = locationCb,
.status_cb = statusCb,
.sv_status_cb = gpsSvStatusCb,
.nmea_cb = nmeaCb,
.set_capabilities_cb = setCapabilitiesCb,
.acquire_wakelock_cb = acquireWakelockCb,
.release_wakelock_cb = releaseWakelockCb,
.create_thread_cb = createThreadCb,
.request_utc_time_cb = requestUtcTimeCb,
.set_system_info_cb = setSystemInfoCb,
.gnss_sv_status_cb = gnssSvStatusCb,
};
void MtkGnss::locationCb(GpsLocation* location) {
auto ret = sGnssCbIface->gnssLocationCb(gnssLocation);
往下层走 gps\gps_hal\src\gpsinf3337.c
/* the name of the controlled socket */
#define GPS_POWER_NAME "/dev/gps"
#define GPS_TTY_NAME "/dev/ttyMT1"
static const GpsInterface mtkGpsInterface = {
sizeof(GpsInterface),
mtk_gps_mt3337_init,
mtk_gps_mt3337_start,
mtk_gps_mt3337_stop,
mtk_gps_mt3337_cleanup,
mtk_gps_mt3337_inject_time,
mtk_gps_mt3337_inject_location,
mtk_gps_mt3337_delete_aiding_data,
mtk_gps_mt3337_set_position_mode,
mtk_gps_mt3337_get_extension,
};
=====================================================================
gps_hal/gpshal_worker.c
static mnl2hal_interface gpshal_mnl2hal_interface = {
update_mnld_reboot,
update_location,
update_gps_status,
update_gps_sv,
update_nmea,
update_gps_capabilities,
update_gps_measurements,
update_gps_navigation,
update_gnss_measurements,
update_gnss_navigation,
request_wakelock,
release_wakelock,
request_utc_time,
request_data_conn,
release_data_conn,
request_ni_notify,
request_set_id,
request_ref_loc,
output_vzw_debug,
};
void gpshal_worker_thread(__unused void *arg) {
for (i = 0; i < n; i++) {
if (events[i].data.fd == g_gpshal_ctx.fd_mnl2hal) {
if (events[i].events & EPOLLIN) {
mnl2hal_hdlr(g_gpshal_ctx.fd_mnl2hal,
&gpshal_mnl2hal_interface);
}
=====================================================================
gps_hal/src/ hal2mnl_interface.c
// -1 means failure
int mnl2hal_hdlr(int fd, mnl2hal_interface* hdlr) {
char buff[HAL_MNL_BUFF_SIZE] = {0};
int offset = 0;
int ver;
mnl2hal_cmd cmd;
int read_len;
int ret = 0;
read_len = safe_recvfrom(fd, buff, sizeof(buff)); / 从底层传上来
case MNL2HAL_LOCATION: {
if (report_time_interval > ++count) {
LOGD("count is %f, interval is %f\n", count, report_time_interval);
break;
}
count = 0;
if (hdlr->location) {
gps_location location;
get_binary(buff, &offset, (char*)&location, sizeof(buff), sizeof(gps_location));
hdlr->location(location);
} else {