#夏日挑战赛#OpenHarmony 源码分析之位置服务子系统 原创 精华
本文正在参加星光计划3.0–夏日挑战赛
作者:巴延兴
1. 简介
位置服务子系统通过GNSS、网络定位技术获取实时准确的设备位置数据, 提供设备定位能力
1.1 OpenHarmony架构图
1.2 子系统架构图
2. 源码分析
2.1 IDL接口
-
ILocator: 提供Locator服务对外SDK接口,包含定位开/关、启动/停止、回调注册、位置上报等;
-
ILocatorCallback: 提供位置信息、定位状态(启动/停止)、异常状态回调接口;
-
ISwitchCallBack: 提供位置服务开关状态回调接口
-
IGeoConvert: 提供地理编码服务相关接口
-
IGnssAbility: 提供GNSS服务相关接口
-
INetWorkAbility: 提供网络定位服务接口
-
IPassiveAbility: 提供被动定位服务接口
-
ILocationCallback: 提供驱动框架(GNSS HDI)位置信息回调接口
定位请求(RequestConfig)定义如下:
class RequestConfig : public Parcelable {
...
void ReadFromParcel(Parcel& parcel);
bool Marshalling(Parcel& parcel) const override;
std::string ToString() const;
static std::unique\_ptr\<RequestConfig\> Unmarshalling(Parcel& parcel);
void Set(RequestConfig& requestConfig);
bool IsSame(RequestConfig& requestConfig);
int scenario\_;
int timeInterval\_;
int distanceInterval\_;
float maxAccuracy\_;
int fixNumber\_;
int priority\_;
};
- scenario_: 定位场景,取值范围如下,用于设置定位方式。
enum {
SCENE\_UNSET = 0x0300,
SCENE\_NAVIGATION = 0x0301, // 该场景,采用GPS定位
SCENE\_TRAJECTORY\_TRACKING = 0x0302, // 该场景,采用GPS定位
SCENE\_CAR\_HAILING = 0x0303, // 该场景,采用GPS定位
SCENE\_DAILY\_LIFE\_SERVICE = 0x0304, // 该场景,采用network定位
SCENE\_NO\_POWER = 0x0305 // 该场景,采用passive定位
};
- priority_:优先级,取值范围如下,当未设置定位场景(SCENE_UNSET)时,用于设置定位方式
enum {
PRIORITY\_UNSET = 0x0200,
PRIORITY\_ACCURACY = 0x0201, // 采用GPS定位
PRIORITY\_LOW\_POWER = 0x0202, // 采用passive定位
PRIORITY\_FAST\_FIRST\_FIX = 0x0203 // 采用gnss network同时定位
};
-
timeInterval_:用于设置上报频率
-
maxAccuracy_:用于设置定位精度
-
fixNumber_:上报次数;0-不限次数,1-N: 仅上报一次
2.2 IDL接口调用关系
-
LocatorAbility: ILocator接口类的服务端实现,位置服务核心单例类,负责维护定位请求及回调对象列表;
-
LocatorHandler: 事件处理类,主要负责:
1)定位开关状态变化时,通知lbsservice_gnss、lbsservice_network或lbsservice_passive发布或删除对应的sa服务,通过ISwitchCallback上报开关状态;
2)定位信息上报或设备唤醒时,刷新当前请求列表,获取定位信息;
-
RequestManager: 定位请求管理类
-
ReportManager: 定位信息上报管理类;
2.4 位置服务启动流程
系统启动后,sa_main读取/system/profile/locationhub.xml (具体内容如下) 动态加载lbsservice_locator、lbsservice_gnss、lbsservice_network、lbsservice_passive以及lbsservice_geocode,启动位置服务进程locationhub。
1)通过GeoConvertService::OnStart向samgr注册ID为2801的sa服务;
2)通过LocatorAbility::OnStart向samgr注册ID为2802的sa服务;
3)通过GnssAbility::OnStart向samgr注册ID为2803的sa服务;
4)通过NetworkAbility::OnStart向samgr注册ID为sa为2804的sa服务;
5)通过PassiveAbility::OnStart向samgr注册ID为2805的sa服务;
\<?xml version="1.0" encoding="utf-8"?\>
\<info\>
\<process\>locationhub\</process\>
\<loadlibs\>
\<libpath\>liblbsservice\_geocode.z.so\</libpath\>
\<libpath\>liblbsservice\_locator.z.so\</libpath\>
\<libpath\>liblbsservice\_gnss.z.so\</libpath\>
\<libpath\>liblbsservice\_network.z.so\</libpath\>
\<libpath\>liblbsservice\_passive.z.so\</libpath\>
\</loadlibs\>
\<systemability\>
\<name\>2801\</name\>
\<libpath\>liblbsservice\_geocode.z.so\</libpath\>
\<run-on-create\>true\</run-on-create\>
\<distributed\>false\</distributed\>
\<dump-level\>1\</dump-level\>
\</systemability\>
\<systemability\>
\<name\>2802\</name\>
\<libpath\>liblbsservice\_locator.z.so\</libpath\>
\<run-on-create\>true\</run-on-create\>
\<distributed\>false\</distributed\>
\<dump-level\>1\</dump-level\>
\</systemability\>
\<systemability\>
\<name\>2803\</name\>
\<libpath\>liblbsservice\_gnss.z.so\</libpath\>
\<run-on-create\>true\</run-on-create\>
\<distributed\>false\</distributed\>
\<dump-level\>1\</dump-level\>
\</systemability\>
\<systemability\>
\<name\>2804\</name\>
\<libpath\>liblbsservice\_network.z.so\</libpath\>
\<run-on-create\>true\</run-on-create\>
\<distributed\>false\</distributed\>
\<dump-level\>1\</dump-level\>
\</systemability\>
\<systemability\>
\<name\>2805\</name\>
\<libpath\>liblbsservice\_passive.z.so\</libpath\>
\<run-on-create\>true\</run-on-create\>
\<distributed\>false\</distributed\>
\<dump-level\>1\</dump-level\>
\</systemability\>
\</info\>
2.5 位置服务使能流程
流程说明:
1)用户通过Locator接口类EnableAbility 打开或关闭定位时,内部实现会调用LocatorProxy发送ENABLE_ABILITY消息给locationhub服务端;
2)服务端LocatorAbilityStub收到ENABLE_ABILITY消息后,通过CheckLocationPermission进行权限校验,校验通过后执行LocatorAbility::EnableAbility;
3)调用LocationConfigManager::SetLocationSwitchState写入当前开关状态;
4)执行LocatorAbility::UpdateSaAbility, 内部会通过LocatorHandler发送并处理EVENT_UPDATE_SA事件,注册或删除ID为2803(gps)、2804(passive)、2805(network)对应的sa服务;
2.6 开始定位流程
流程说明:
1)用户通过Locator接口类StartLocating启动定位,内部实现会调用LocatorProxy发送START_LOCATING消息给locationhub服务端;
2)服务端LocatorAbilityStub收到START_LOCATING消息后,通过CheckLocationPermission进行权限校验,校验通过后执行LocatorAbility::StartLocating;
3)校验定位是否开启,若没有则上报ERROR_SWITCH_UNOPEN状态,StartLocating流程结束;
4)校验gps、network、passive对应sa代理服务是否存在,若没有则执行InitSaAbility重新获取;
5)创建Request, 记录客户端uid,pid,packagename及下发的RequestConfig,调用RequestManager::HandleStartLocating处理定位请求;
-
调用RestorRequest,将Request插入到ILocatorCallback对象关联的请求列表中,相同定位场景或优先级视为重复RequestConfig,不插入;
-
调用UpdateRequestRecord,根据下发的RequestConfig获取对应sa代理服务(例如SCENE_NAVIGATION对应的gps服务),在该sa代理服务关联的请求列表中插入Request;
-
调用HandleRequest处理gps、network、passive对应请求列表,调用SendLocationRequest发送SEND_LOCATION_REQUEST消息码给对应sa服务处理;
6)调用ReportLocationStatus上报SESSION_START状态
2.7 定位上报流程
流程说明:
1) 当GPS硬件检查到位置变化时,发送RECEIVE_LOCATION_CHANGE_EVENT通知位置服务locationhub;
2) 位置服务LocationCallbackStub收到消息后,执行OnLocationChange;
3) 调用init创建LocatorProxy对象
4) 调用LocatorProxy::ReportLocation发送REPORT_LOCATION消息;
5)LocatorAbilityStub收到REPORT_LOCATION消息,转发给LocatorAbility处理;
6)LocatorAbility执行ReportManager::OnReportLocation上报定位数据
-
FusionController::FuseResult删除启动定位时新增的WorkRecord;
-
遍历定位请求列表
-
ReportIntervalCheck 校验当前定位数据是否符合上报频率
-
MaxAccuracyCheck 对定位数据进行精度校验
-
调用LocatorCallbackProxy::OnLocationReport上报定位信息给用户
-
校验定位请求RequestConfig中上报次数,若不为0,则执行UpdateRequestRecord删除定位请求
-
通过LocatorHandler发送定时EVENT_APPLY_REQUIREMENTS事件,调用RequestManager::HandleRequest处理所有请求列表
更多原创内容请关注:深开鸿技术团队
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
图片有点看不清,大佬能传一份到附件中吗?