android7.1 location service

一、在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时会调用LocationManagerServicesystemRunning接口,进而调用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();

}

 

mHandlerGnssLocationProvider构造函数中初始化

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,主要是获取halidGPS_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 &params)

{

       ......

    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.cpploc_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继承于LocAdapterBasesendMsg方法也直接继承父类方法,在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");

}

输入参数contextretVal = 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是什么?mLocApiLocEngAdapter的父类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)mLocApiLocApiV02对象,所以到这里,就执行到了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_syncMODEM发送数据了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值