在gps定位的apk中,启动GPS的方法如下,
mLocationManager.requestLocationUpdates(provider, 500, 0, mLocationListener);
调用LocationManager的requestLocationUpdates方法,调用流程图如下,
在startNavigating方法中,首先获取系统支持的GPS工作模式,主要有三种,
private static final int GPS_POSITION_MODE_STANDALONE = 0;//仅GPS工作
private static final int GPS_POSITION_MODE_MS_BASED = 1;// AGPS MSB模式
private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;// AGPS MSA模式
当然,这三种模式在gps.h也有对应的定义,定义如下,
#define GPS_POSITION_MODE_STANDALONE 0
#define GPS_POSITION_MODE_MS_BASED 1
#define GPS_POSITION_MODE_MS_ASSISTED 2
调用native_set_position_mode方法进行设置。然后调用native_start方法启动GPS。
com_android_server_location_GpsLocationProvider的方法如下,
static jboolean android_location_GpsLocationProvider_start(JNIEnv* /* env */, jobject /* obj */)
{
if (sGpsInterface) {
if (sGpsInterface->start() == 0) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
}
else
return JNI_FALSE;
}
直接调用HAL的start方法,对应的方法为loc.cpp中的loc_start方法,
static int loc_start()
{
ENTRY_LOG();
int ret_val = loc_eng_start(loc_afw_data);
EXIT_LOG(%d, ret_val);
if (writeValue(high) < 0){
return -1;
}
return ret_val;
}
loc_afw_data在loc_init方法中进行初始化, loc_afw_data是loc_eng_data_s_type类型的结构体,在loc_eng.h中定义的。
整个流程图如下,
loc_eng.cpp的方法如下,
int loc_eng_start(loc_eng_data_s_type &loc_eng_data)
{
ENTRY_LOG_CALLFLOW();
INIT_CHECK(loc_eng_data.adapter, return -1);
if(! loc_eng_data.adapter->getUlpProxy()->sendStartFix())
{
loc_eng_data.adapter->sendMsg(new LocEngStartFix(loc_eng_data.adapter));
}
EXIT_LOG(%d, 0);
return 0;
}
loc_eng_data.adapter指向的是LocEngAdapter对象,最后实际调用的是MsgTask.cpp方法,
void MsgTask::sendMsg(const LocMsg* msg) const {
msg_q_snd((void*)mQ, (void*)msg, LocMsgDestroy);
}
sendMsg函数通过msg_q_snd会把msg发送到消息队列mQ中:
msq_q_err_type msg_q_snd(void* msg_q_data, void* msg_obj, void (*dealloc)(void*))
{
msq_q_err_type rv;
if( msg_q_data == NULL )
{
LOC_LOGE("%s: Invalid msg_q_data parameter!\n", __FUNCTION__);
return eMSG_Q_INVALID_HANDLE;
}
if( msg_obj == NULL )
{
LOC_LOGE("%s: Invalid msg_obj parameter!\n", __FUNCTION__);
return eMSG_Q_INVALID_PARAMETER;
}
msg_q* p_msg_q = (msg_q*)msg_q_data;
pthread_mutex_lock(&p_msg_q->list_mutex);
LOC_LOGV("%s: Sending message with handle = 0x%08X\n", __FUNCTION__, msg_obj);
if( p_msg_q->unblocked )
{
LOC_LOGE("%s: Message queue has been unblocked.\n", __FUNCTION__);
pthread_mutex_unlock(&p_msg_q->list_mutex);
return eMSG_Q_UNAVAILABLE_RESOURCE;
}
rv = convert_linked_list_err_type(linked_list_add(p_msg_q->msg_list, msg_obj, dealloc));
/* Show data is in the message queue. */
pthread_cond_signal(&p_msg_q->list_cond);
pthread_mutex_unlock(&p_msg_q->list_mutex);
LOC_LOGV("%s: Finished Sending message with handle = 0x%08X\n", __FUNCTION__, msg_obj);
return rv;
}
在MsgTask.cpp的MsgTask构造方法中,
MsgTask::MsgTask(LocThread::tCreate tCreator,
const char* threadName, bool joinable) :
mQ(msg_q_init2()), mThread(new LocThread()) {
if (!mThread->start(tCreator, threadName, this, joinable)) {
delete mThread;
mThread = NULL;
}
}
MsgTask开启一子线程并运行,run方法如下,
bool MsgTask::run() {
LOC_LOGV("MsgTask::loop() listening ...\n");
LocMsg* msg;
msq_q_err_type result = msg_q_rcv((void*)mQ, (void **)&msg);
if (eMSG_Q_SUCCESS != result) {
LOC_LOGE("%s:%d] fail receiving msg: %s\n", __func__, __LINE__,
loc_get_msg_q_status(result));
return false;
}
msg->log();
// there is where each individual msg handling is invoked
msg->proc();
delete msg;
return true;
}
Modem的定位消息传到AP侧之后,就可以通过run函数调用msg_q_rcv接受消息队列mQ的消息,
读取msg,依次执行msg的log()和proc()。这部分内容后面再论述。