一、在App中调用位置服务
LocationManager mLocationManager =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Locationlocation) {
// 位置信息变化时触发
;
}
@Override
public voidonstatusChanged(String provider, int status, Bundle extras) {
// GPS状态变化时触发
}
@Override
public voidonProviderDisabled(String provider) {
// GPS 开启时触发
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0, 0, locationListener);
二、框架层
LocationManager类的实现 /frameworks/base/location/java/android/location/LocationManager.java
接口定义
/frameworks/base/location/java/android/location/ILocationManager.aidl
LocationManagerService类的实现
/frameworks/base/services/core/java/com/android/server/LocationManagerService.java
requestLocationUpdates分析
LocationManagerService.java
requestLocationUpdates -> requestLocationUpdatesLocked -> applyRequirementsLocked
在applyRequirementsLocked中
private void applyRequirementsLocked(String provider) {
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null)return;
......
p.setRequest(providerRequest,worksource);
}
mProvidersByName里面的内容在什么时候添加进来?
mProvidersByName的定义如下:
private final HashMap<String,LocationProviderInterface> mProvidersByName =
newHashMap<String, LocationProviderInterface>();
通过addProviderLocked接口往里面添加数据
private void addProviderLocked(LocationProviderInterfaceprovider) {
mProviders.add(provider);
mProvidersByName.put(provider.getName(), provider);
}
在SystemServer启动后(SystemServer.java, main -> run -> startOtherServices-> locationF.systemRunning),在startOtherServices时会调用LocationManagerService的systemRunning接口,进而调用loadProvidersLocked添加各种类型的provider
SystemServer启动流程:http://blog.csdn.net/cloudwu007/article/details/6701765
public void systemRunning() {
......
// prepareproviders
loadProvidersLocked();
}
private void loadProvidersLocked() {
......
if(GnssLocationProvider.isSupported()) {
// Create a gps location provider
GnssLocationProvider gnssProvider = newGnssLocationProvider(mContext, this, mLocationHandler.getLooper());
mGnssSystemInfoProvider= gnssProvider.getGnssSystemInfoProvider();
mGnssStatusProvider = gnssProvider.getGnssStatusProvider();
mNetInitiatedListener = gnssProvider.getNetInitiatedListener();
addProviderLocked(gnssProvider);
mRealProviders.put(LocationManager.GPS_PROVIDER, gnssProvider);
mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider();
mGnssNavigationMessageProvider =gnssProvider.getGnssNavigationMessageProvider();
mGpsGeofenceProxy = gnssProvider.getGpsGeofenceProxy();
}
......
}
再回到applyRequirementsLocked方法,当参数为LocationManager.GPS_PROVIDER时,p即为GnssLocationProvider,继续看p.setRequest(providerRequest, worksource);
GnssLocationProvider.java
public void setRequest(ProviderRequest request, WorkSourcesource) {
sendMessage(SET_REQUEST,0, new GpsRequest(request, source));
}
private void sendMessage(int message, int arg, Object obj) {
mWakeLock.acquire();
mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
}
mHandler在GnssLocationProvider构造函数中初始化
mHandler = new ProviderHandler(looper);
消息处理函数如下:
public void handleMessage(Message msg) {
int message =msg.what;
switch (message) {
caseSET_REQUEST:
GpsRequest gpsRequest = (GpsRequest)msg.obj;
handleSetRequest(gpsRequest.request,gpsRequest.source);
break;
......
}
}
private void handleSetRequest(ProviderRequest request,WorkSource source) {
mProviderRequest =request;
mWorkSource =source;
updateRequirements();
}
private void updateRequirements() {
......
if (mProviderRequest.reportLocation&& !mDisableGps && isEnabled()) {
// updateclient uids
updateClientUids(mWorkSource);
mFixInterval =(int) mProviderRequest.interval;
// check foroverflow
if(mFixInterval != mProviderRequest.interval) {
Log.w(TAG,"interval overflow: " + mProviderRequest.interval);
mFixInterval = Integer.MAX_VALUE;
}
// applyrequest to GPS engine
if (mStarted&& hasCapability(GPS_CAPABILITY_SCHEDULING)) {
// changeperiod
if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
mFixInterval, 0, 0)) {
Log.e(TAG,"set_position_mode failed in setMinTime()");
}
} else if(!mStarted) {
// startGPS
startNavigating(singleShot);
}
} else {
updateClientUids(new WorkSource());
stopNavigating();
mAlarmManager.cancel(mWakeupIntent);
mAlarmManager.cancel(mTimeoutIntent);
}
}
startNavigating 最终也会调用到 native_set_position_mode
stopNavigating 调用到 native_stop();
从而进入到了jni 层
三、JNI层和HAL层
/frameworks/base/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
jni层初始化:在GnssLocationProvider.java中有静态代码段
static { class_init_native(); },对应native层的android_location_GnssLocationProvider_class_init_native,主要是获取hal层id为GPS_HARDWARE_MODULE_ID 的module接口函数。
在/hardware/qcom/gps/msm8909/loc_api/libloc_api_50001/Gps.c 中,有如下定义
struct hw_module_t HAL_MODULE_INFO_SYM = {
.tag =HARDWARE_MODULE_TAG,
.module_api_version= 1,
.hal_api_version =0,
.id =GPS_HARDWARE_MODULE_ID,
.name ="loc_api GPS Module",
.author ="Qualcomm USA, Inc.",
.methods =&gps_module_methods,
};
从而得知,
sGpsInterface
= gps_device->get_gps_interface(gps_device)
= gps__get_gps_interface(gps_device)
= get_gps_interface(/hardware/qcom/msm89009/loc_api/libloc_api_50001/loc.cpp)
= sLocEngInterface
在loc.cpp中,sLocEngInterface定义如下:
static const GpsInterface sLocEngInterface =
{
sizeof(GpsInterface),
loc_init,
loc_start,
loc_stop,
loc_cleanup,
loc_inject_time,
loc_inject_location,
loc_delete_aiding_data,
loc_set_position_mode,
loc_get_extension
};
初始化工作了解完之后,继续之前的分析,
native_set_position_mode
---> android_location_GnssLocationProvider_set_position_mode
---> sGpsInterface-> set_position_mode
---> loc_set_position_mode
---> loc_eng_set_position_mode
路径:/hardware/qcom/gps/msm8909/loc_api/libloc_api_50001/Loc_eng.cpp
int loc_eng_set_position_mode(loc_eng_data_s_type&loc_eng_data,
LocPosMode ¶ms)
{
......
if(!loc_eng_data.adapter->getUlpProxy()->sendFixMode(params))
{
LocEngAdapter*adapter = loc_eng_data.adapter;
adapter->sendMsg(new LocEngPositionMode(adapter, params));
}
return 0;
}
到这里,需要先分析一下loc_eng_data及其成员变量adapter,参数 loc_eng_data 的值是全局变量loc_afw_data,在loc_init 中被初始化
loc_init.cpp中loc_init函数会调用loc_eng_init初始化loc_afw_data
retVal = loc_eng_init(loc_afw_data, &clientCallbacks,event, NULL);
loc_eng_init.cpp中
loc_eng_data.adapter = new LocEngAdapter(event,&loc_eng_data, context,
(LocThread::tCreate)callbacks->create_thread_cb);
LocEngAdapter继承于LocAdapterBase,sendMsg方法也直接继承父类方法,在LocAdapterBase.h中,有如下定义:
inline void sendMsg(const LocMsg* msg) {
mMsgTask->sendMsg(msg);
}
mMsgTask在构造函数中初始化:
LocAdapterBase::LocAdapterBase(constLOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context,LocAdapterProxyBase *adapterProxyBase) :
mEvtMask(mask),mContext(context),
mLocApi(context->getLocApi()),mLocAdapterProxyBase(adapterProxyBase),
mMsgTask(context->getMsgTask())
{
mLocApi->addAdapter(this);
}
context的值是什么呢?看LocEngAdapter的构造函数
LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask,
void* owner,ContextBase* context, LocThread::tCreate tCreator) :
LocAdapterBase(mask,
context ==NULL?
LocDualContext::getLocFgContext(tCreator,
NULL,
LocDualContext::mLocationHalName,
false)
:context),
mOwner(owner),mInternalAdapter(new LocInternalAdapter(this)),
mUlp(newUlpProxyBase()), mNavigating(false),
mSupportsAgpsRequests(false),
mSupportsPositionInjection(false),
mSupportsTimeInjection(false),
mPowerVote(0)
{
memset(&mFixCriteria, 0, sizeof(mFixCriteria));
mFixCriteria.mode =LOC_POSITION_MODE_INVALID;
LOC_LOGD("LocEngAdapter created");
}
输入参数context从retVal = loc_eng_init(loc_afw_data, &clientCallbacks,event, NULL)开始传进来,值为NULL,所以
context = LocDualContext::getLocFgContext(tCreator,
NULL,
LocDualContext::mLocationHalName,
false);
ContextBase*LocDualContext::getLocFgContext(LocThread::tCreate tCreator,
LocMsg*firstMsg, const char* name, bool joinable)
{
pthread_mutex_lock(&LocDualContext::mGetLocContextMutex);
if (NULL ==mFgContext) {
const MsgTask*msgTask = getMsgTask(tCreator, name, joinable);
mFgContext = newLocDualContext(msgTask, mFgExclMask);
}
if(NULL ==mInjectContext) {
mInjectContext= mFgContext;
injectFeatureConfig(mInjectContext);
}
pthread_mutex_unlock(&LocDualContext::mGetLocContextMutex);
if (firstMsg) {
mFgContext->sendMsg(firstMsg);
}
return mFgContext;
}
ok,到这里,我们可以回答context是什么了,context是一个LocDualContext对象,继承于ContextBase。
继续之前的分析mMsgTask = context->getMsgTask();
const MsgTask* LocDualContext::getMsgTask(LocThread::tCreatetCreator,
constchar* name, bool joinable)
{
if (NULL ==mMsgTask) {
mMsgTask = newMsgTask(tCreator, name, joinable);
}
return mMsgTask;
}
可以看到mMsgTask是一个MsgTask对象,在 /hardware/qcom/gps/msm8909/utils/MsgTask.cpp中实现,该对象创建时会启动一个线程,线程的主要工作就是不断的从消息队列中取出msg,然后执行msg->log()和msg->proc(),而sendMsg方法就是往消息队列里面添加msg
现在回到loc_eng_set_position_mode方法中,adapter->sendMsg(new LocEngPositionMode(adapter, params))就会执行LocEngPositionMode实例的proc方法
inline void LocEngPositionMode::proc() const {
mAdapter->setPositionMode(&mPosMode);
}
mAdapter即为loc_eng_data.adapter
inline enum loc_api_adapter_err
setPositionMode(const LocPosMode *posMode)
{
if (NULL !=posMode) {
mFixCriteria =*posMode;
}
returnmLocApi->setPositionMode(mFixCriteria);
}
mLocApi是什么?mLocApi在LocEngAdapter的父类LocAdapterBase的构造函数中中初始化,mLocApi(context->getLocApi()),这里的context即为之前分析的context,是LocDualContext类型的对象
看LocDualContext及其父类ContextBase的构造函数:
LocDualContext::LocDualContext(const MsgTask* msgTask,
LOC_API_ADAPTER_EVENT_MASK_T exMask) :
ContextBase(msgTask, exMask, mLBSLibName)
{ // 这里mLBSLibName = "liblbs_core.so";
}
ContextBase::ContextBase(const MsgTask* msgTask,
LOC_API_ADAPTER_EVENT_MASK_T exMask,
const char* libName) :
mLBSProxy(getLBSProxy(libName)),
mMsgTask(msgTask),
mLocApi(createLocApi(exMask)),
mLocApiProxy(mLocApi->getLocApiProxy())
{
}
LBSProxyBase* ContextBase::getLBSProxy(const char* libName)
{
LBSProxyBase* proxy= NULL;
// 这里libName =" liblbs_core.so ",目前我们的系统里面没有这个库
void* lib =dlopen(libName, RTLD_NOW);
if ((void*)NULL !=lib) {
getLBSProxy_t*getter = (getLBSProxy_t*)dlsym(lib, "getLBSProxy");
if (NULL !=getter) {
proxy =(*getter)();
}
}
if (NULL == proxy){
proxy = newLBSProxyBase(); // 所以最终会返回一个LBSProxyBase对象
}
return proxy;
}
LocApiBase*ContextBase::createLocApi(LOC_API_ADAPTER_EVENT_MASK_T exMask)
{
LocApiBase* locApi= NULL;
// Check the target
if (TARGET_NO_GNSS!= loc_get_target()){
// 之前mLBSProxy是一个LBSProxyBase对象,所以
// mLBSProxy->getLocApi固定返回NULL
if (NULL ==(locApi = mLBSProxy->getLocApi(mMsgTask, exMask, this))) {
void*handle = NULL;
//我们的系统中存在libloc_api_v02.so
//在/device/qcom/msm8909w/opensource/location/loc_api/loc_api_v02中
//Android.mk中有定义 LOCAL_MODULE := libloc_api_v02
//try tosee if LocApiV02 is present
if ((handle= dlopen("libloc_api_v02.so", RTLD_NOW)) != NULL) {
getLocApi_t* getter = (getLocApi_t*) dlsym(handle,"getLocApi");
if(getter != NULL) {
locApi = (*getter)(mMsgTask, exMask, this);
}
}
// only RPCis the option now
else {
......
}
}
}
......
return locApi;
}
/device/qcom/msm8909w/opensource/location/loc_api/loc_api_v02/LocApiV02.cpp中,有找到getLocApi的实现:
LocApiBase* getLocApi(const MsgTask *msgTask,
LOC_API_ADAPTER_EVENT_MASK_T exMask,
ContextBase* context)
{
return newLocApiV02(msgTask, exMask, context);
}
回到mLocApi->setPositionMode(mFixCriteria),mLocApi为LocApiV02对象,所以到这里,就执行到了libloc_api_v02.so中
enum loc_api_adapter_err LocApiV02 :: setPositionMode(
const LocPosMode&posMode)
{
if(isInSession())
{
//fix is inprogress, send a restart
return(startFix(posMode));
}
returnLOC_API_ADAPTER_ERR_SUCCESS;
}
libloc_api_v02.so主要的工作是对前面的接口进行一次封装后,通过qmi_client_send_msg_sync给MODEM发送数据了。