android gps机制分析--之四

2,启动GPS

2.1 Java层分析

在gps定位的apk中,启动GPS的方法如下,

mLocationManager.requestLocationUpdates(provider, 500, 0, mLocationListener);

调用LocationManager的requestLocationUpdates方法,调用流程图如下,

android gps机制分析--之四_第1张图片

在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。


2.2 HAL 层启动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中定义的。

整个流程图如下,

android gps机制分析--之四_第2张图片

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()。这部分内容后面再论述。

你可能感兴趣的:(---【gps框架分析】)