本文正在參加星光計劃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上報定位資訊給使用者