Android

GPS数据流程分析

概述:

该文档将介绍android

GPS数据流程分析,在debug的时候可以做为数据流的捕捉的参考。

=============================================================

在介绍数据流之前首先介绍的数据在hal层究竟从哪里来的,也就是原生的没经过解码的数据时从哪儿来的,首先进入到hardware下创建RPC通讯的地方开始,也就是创建一个RPC

client,也就是loc_api_glue_init函数做这件事情:

进入到loc_api_glue_init=>

clnt_create:

CLIENT

*clnt_create(

char

* host,

uint32

prog,

uint32

vers,

char

* proto)

{

…………………………………………………………….

client->xdr

=xdr_init_common(name,

1 /* client XDR */);

…………………………………………………………………

if

(!num_clients++) {

D("launching

RX thread.\n");

pthread_create(&rx_thread,

NULL,rx_context,NULL);

}

else {

/*

client added, wake up rx_thread */

if

(write(wakeup_pipe[1], "a", 1) < 0)

E("error

writing to pipe\n");

}

……………………………………………………………………

}

NOTE:XDR是一个数据描述和数据编码的标准,它对于不同架构计算机之间的数据传输是非常有用的。

RPC是计算机之间的远过程调用协议。

RPC使用XDR描述它的数据格式的。

=============================================================

这个函数有两个功能:

初始化相关的XDR读取RPC数据的方法。

创建一个线程rx_context去接收RPC的数据。

对于前者主要的:

xdr_s_type

*xdr_init_common(const char *router, int is_client)

{

xdr_s_type

*xdr = (xdr_s_type *)calloc(1, sizeof(xdr_s_type));

xdr->xops

= &xdr_std_xops;

……………………………

return

xdr;

}

实际上xdr_std_xops是xdr操作的各种方法

const

xdr_ops_s_type xdr_std_xops = {

xdr_std_destroy,

xdr_std_control,

xdr_std_read,//读数据

xdr_std_msg_done,

xdr_std_msg_start,

xdr_std_msg_abort,

xdr_std_msg_send,

/*数据编码*/

xdr_std_send_int8,

xdr_std_send_uint8,

xdr_std_send_int16,

xdr_std_send_uint16,

xdr_std_send_int32,

xdr_std_send_uint32,

xdr_std_send_bytes,

/*数据解码*/

xdr_std_recv_int8,

xdr_std_recv_uint8,

xdr_std_recv_int16,

xdr_std_recv_uint16,

xdr_std_recv_int32,

xdr_std_recv_uint32,

xdr_std_recv_bytes,

};

对于后者创建一个线程去读取RPC数据:

static

void *rx_context(void *__u __attribute__((unused)))

{

……………………………………………..

ret

= client->xdr->xops->read(client->xdr);

if

(ret == FALSE) {

E("%08x:%08x

xops->read() error %s (%d)\n",

client->xdr->x_prog,

client->xdr->x_vers,

strerror(errno),

errno);

……………………………………………….

}

通过ret

= client->xdr->xops->read(client->xdr);读取rpc数据,这个read函数的

注册实际上就在xdr_init_common里面,那么到这个我已经知道数据从哪儿来的了,后面介绍jni与hal层交互的数据过程:

回到hardware/qcom/gps/loc_api/libloc_api/loc_eng.cpp的loc_eng_init

中的loc_eng_data.client_handle

= loc_open (event, loc_event_cb);

这个函数主要的目的是打开前面创建的rpc

client并把相关的数据提交上报的

过程:

首先看loc_event_cb这个函数,

static

int32 loc_event_cb( )

{

if

(client_handle == loc_eng_data.client_handle)

{

………………………………………………..

memcpy(&loc_eng_data.loc_event_payload,

loc_event_payload, sizeof(*loc_event_payload));

………………………………………………..

pthread_cond_signal

(&loc_eng_data.deferred_action_cond);

pthread_mutex_unlock

(&loc_eng_data.deferred_action_mutex);

}

}

这个函数主要完成的功能是

1、将接收到的数据搬移

2、发送一个信号给处理这个数据的线程

进到处理这个数据的线程:

进入到这个函数中loc_eng_process_deferred_action,这也是一个线程专门用于处理数据,在init的时候被创建:

调用函数loc_eng_process_deferred_action=>

loc_eng_report_position真正的实现数据的上报到jni层,进入到函数loc_eng_report_position看看:

static

void loc_eng_report_position (const rpc_loc_parsed_position_s_type

*location_report_ptr)

{

GpsLocation

location;

……………………………………………………

if

(location_report_ptr->valid_mask &

RPC_LOC_POS_VALID_HOR_UNC_CIRCULAR)

{

location.flags

|= GPS_LOCATION_HAS_ACCURACY;

location.accuracy

= location_report_ptr->hor_unc_circular;

}

if

(loc_eng_data.location_cb != NULL)

{

LOGV

("loc_eng_report_position: fire callback\n");

loc_eng_data.location_cb

(&location);

}

}

}

最关键的是loc_eng_data.location_cb

(&location);调用这个函数的时候相当于真正调的是jni注册到hal的函数,通过这种方式就实现了jni与hal的数据传递了。

再回到loc_open这个函数:

在loc_open中将通过这句话loc_glue_callback_table[i].cb_func

= event_callback;

将loc_event_cb注册给了loc_glue_callback_table[i],那么什么时候真正的调用呢?

在qcom/proprietary/gps/loc_api/libloc-rpc/src/loc_api_rpc_glue.c的

rpc_loc_event_cb_f_type_svc中实现了真正的调用,

后续的调用关系如下:

rpc_loc_event_cb_f_type_svc=>RPC_CALLBACK_FUNC_VERSION(rpc_loc_event_cb_f_type_,

RPC_LOC_EVENT_CB_F_TYPE_VERSION, _svc) =>

rpc_loc_event_cb_f_type_0x00050001_svc

在qcom/proprietary/modem-apis/msm7627_ktouch/api/libs/remote_apis/loc_api/rpcgen/src/loc_api_rpcgen_cb_svc.c

+45

有函数loc_apicbprog_0x00050001将rpc_loc_event_cb_f_type_0x00050001_svc

赋值给了local,后面通过retval

= (bool_t) (*local)((char *)&argument, (void *)&result,

rqstp)实现对rpc_loc_event_cb_f_type_0x00050001_svc真正的调用,

Argument中的内容就是转换之后的数据指针,从哪儿来的呢?

通过svc_getargs这个函数实现的,svc_getargs中的参数_xdr_argument得到了调用,也就是xdr_rpc_loc_event_cb_f_type_args得到了调用,进入这个函数看看:

bool_t

xdr_rpc_loc_event_cb_f_type_args

(XDR *xdrs, rpc_loc_event_cb_f_type_args *objp)

{

if

(!xdr_rpc_uint32(xdrs, &objp->cb_id))

return

FALSE;

if

(!xdr_rpc_loc_client_handle_type (xdrs, &objp->loc_handle))

return

FALSE;

if

(!xdr_rpc_loc_event_mask_type (xdrs, &objp->loc_event))

return

FALSE;

if

(!xdr_pointer (xdrs, (char **)&objp->loc_event_payload, sizeof

(rpc_loc_event_payload_u_type), (xdrproc_t)

xdr_rpc_loc_event_payload_u_type))

return

FALSE;

return

TRUE;

}

也就是xdr_rpc_uint32实现了数据的解码过程

=============================================================

到这里将hal层与jni层的通讯数据的传递分析完了,后面分析jni层的数据时怎么到java层的:

进入jni的函数里面:

进入android_location_GpsLocationProvider_wait_for_event这个函数:

比如位置的信息的上报时通过什么方式的,截取了一段程序如下:

if

(pendingCallbacks & kLocation) {

env->CallVoidMethod(obj,method_reportLocation,sGpsLocationCopy.flags,

(jdouble)sGpsLocationCopy.latitude,

(jdouble)sGpsLocationCopy.longitude,

(jdouble)sGpsLocationCopy.altitude,

(jfloat)sGpsLocationCopy.speed,

(jfloat)sGpsLocationCopy.bearing,

(jfloat)sGpsLocationCopy.accuracy,

(jlong)sGpsLocationCopy.timestamp);

首先当这个线程得到信号sEventCond后就会进入到运行状态,被谁唤醒呢?就是hal掉init的jni的相关回调结束的时候会发送一个信号给该线程,实现线程的同步,

注意到当判断到时位置信息的时候进入到这个分支,调用method_reportLocation这个方法将数据上报,为什么呢?看jni里面这句话

method_reportLocation

= env->GetMethodID(clazz, "reportLocation",

"(IDDDFFFJ)V");

也就是说method_reportLocation映射为java层的reportLocation这种方法,所以

reportLocation这个方法实现在GpsLocationProvider.java中

private

void reportLocation(int flags, double latitude, double longitude,

double altitude,

float

speed, float bearing, float accuracy, long timestamp) {

if

(VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + "

long: " + longitude +

"

timestamp: " + timestamp);

mLastFixTime

= System.currentTimeMillis();

…………………………………………………..

}

到这里数据就已经到java层了。reportLocation这个函数可以认为是java层注册到jni的一个回调,便于两层之间传递数据。

android gps时间格式,android gps 数据传输流程相关推荐

  1. android gps时间格式,android – GPS:NTP时间注入的工作原理

    我最近知道一个gps.conf文件在/ system / etc /目录. 似乎将NTP_SERVER值调整到更接近通常位置的NTP服务器改善了TTFF. 读取LocationProvider类中的源 ...

  2. android 日期键盘,android 日期时间格式转换;软键盘显示消失;获取系统title

    获取activty title bar: TextView actionTitle = (TextView) findViewById(com.android.internal.R.id.action ...

  3. Android各种时间格式转换

    今天就给大家提供一个时间操作的转换类,比较全,大家可以收藏一下,一个满满的DateUtils就这样诞生了. /** * 获取现在时间 * * @return 返回时间类型 yyyy-MM-dd HH: ...

  4. android 常用时间格式转换代码

    /**   * 获取现在时间   *    * @return 返回时间类型 yyyy-MM-dd HH:mm:ss   */ public static Date getNowDate() {   ...

  5. android 日期时间类,Android 时间与日期操作类

    获取本地日期与时间 public String getCalendar() { @SuppressLint("SimpleDateFormat") SimpleDateFormat ...

  6. android格式化时间中文版,Android 仿微信聊天时间格式化显示功能

    本文给大家分享android仿微信聊天时间格式化显示功能. 在同一年的显示规则: 如果是当天显示格式为 HH:mm 例:14:45 如果是昨天,显示格式为 昨天 HH:mm 例:昨天 13:12 如果 ...

  7. android车载支持格式,Android车载版来了:车机实现全部功能

    汽车厂商沃尔沃和奥迪宣布,将与谷歌合作,开发基于Android的车载信息娱乐系统,并直接集成至车辆. 这一合作的详情将在本周晚些时候的谷歌I/O开发者大会上公布.目前已知,这一合作将独立于谷歌当前专注 ...

  8. android列表时间轴,Android实现列表时间轴

    本文实例为大家分享了Android列表时间轴展示的具体代码,供大家参考,具体内容如下 实现的效果图如下: 实现的方式是利用recycleview的ItemDecoration这个抽象类,就是我们经常用 ...

  9. android 自定义时间对话框,android自定义日期和时间选择对话框得实现

    1,先写布局文件,把时间选择器和日期选择器都放到一起去 android:layout_width="match_parent" android:layout_height=&quo ...

最新文章

  1. db2分页查询语句优化_面试官:数据量很大,分页查询很慢,怎么优化?
  2. 贝叶斯优化神经网络参数_贝叶斯超参数优化:神经网络,TensorFlow,相预测示例
  3. Spring集成–第1节– Hello World
  4. 回溯算法解决八皇后_4皇后问题和使用回溯算法的解决方案
  5. 【Flink】Flink keyed State多年的误解 以及 Keyed state redistribute
  6. struts2权威指南学习笔记:struts2引入自定义库
  7. 各种SQL数据库的数据类型
  8. web文件上传(二)--使用form还是ajax
  9. 字符串转数组和数组转字符串
  10. word2vec字向量_Anything2Vec:将Reddit映射到向量空间
  11. 钉钉签到自动签到python_原来实现钉钉自动签到如此简单,每天准时上下班不是梦...
  12. 5款 Linux 常用远程连接工具,总有一款适合你
  13. [乐意黎]某音上超酷炫的 Word Clock 文字云时钟屏保配置
  14. Verilog实现数字时钟
  15. 网络词典[U~Z](转)
  16. 计算机伦理学案例分析,医药伦理学案例分析
  17. 【数据分析项目实战】篇1:游戏数据分析——新增、付费和用户行为评估
  18. 移动端Touch (触摸)事件
  19. 浪潮服务器加速计算系统,超强AI计算系统囊括浪潮人工智能服务器
  20. 链队的创建、入队、出队

热门文章

  1. emif接口速率问题_EMIF接口与FPGA的互联(转)
  2. 微信公众号菜单如何直接跳到微信小程序
  3. linux中setfacl命令,Linux命令之:setfacl和getfacl
  4. 联署计划-三赢的网络营销
  5. std::string::npos 常量解析
  6. 一场特殊发布会与小米的「重新创业」
  7. git删除远程分支问题及git批量删除已合并的远程分支
  8. 【文本聚类】一篇文章弄懂三种聚类算法(K-Means,Agglomerative,DBSCAN)
  9. 【案例拆解】如何利用数据分析手段,有效地驱动产品迭代!
  10. Java实现数组底层