鸿蒙 gnss 发起定位流程

代码还是选取开源鸿蒙HarmonyOS 4.0的代码基线。
这里我们直接看调用发起定位:

// base/location/frameworks/native/source/locator_impl.cpp
void LocatorImpl::StartLocating(std::unique_ptr<RequestConfig>& requestConfig, sptr<ILocatorCallback>& callback)
{
    if (!Init()) {
        return;
    }
    sptr<LocatorProxy> proxy = GetProxy();
    if (proxy == nullptr) {
        LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__);
        return;
    }
    proxy->StartLocating(requestConfig, callback, "location.ILocator", 0, 0);
}

// base/location/frameworks/native/source/locator_proxy.cpp
int LocatorProxy::StartLocating(std::unique_ptr<RequestConfig>& requestConfig,
    sptr<ILocatorCallback>& callback, std::string bundleName, pid_t pid, pid_t uid)
{
    LBSLOGD(LOCATOR_STANDARD, "uid is: %{public}d, pid is: %{public}d", uid, pid);
    MessageParcel data;
    if (!data.WriteInterfaceToken(GetDescriptor())) {
        return REPLY_CODE_EXCEPTION;
    }
    if (requestConfig != nullptr) {
        requestConfig->Marshalling(data);
    }
    if (callback != nullptr) {
        data.WriteObject<IRemoteObject>(callback->AsObject());
    }
    data.WriteString16(Str8ToStr16(bundleName));
    MessageParcel reply;
    int error = SendMsgWithDataReply(static_cast<int>(LocatorInterfaceCode::START_LOCATING), data, reply);
    LBSLOGD(LOCATOR_STANDARD, "Proxy::StartLocating Transact ErrCodes = %{public}d", error);
    return error;
}

// 处理这个消息 START_LOCATING
// base/location/services/location_locator/locator/source/locator_skeleton.cpp
int LocatorAbilityStub::PreStartLocating(MessageParcel &data, MessageParcel &reply, AppIdentity &identity)
{	// 是否打开location 开关
    if (!CheckLocationSwitchState(reply)) {
        return ERRCODE_SWITCH_OFF;
    }
    if (!CheckLocationPermission(reply, identity)) {
        return ERRCODE_PERMISSION_DENIED;
    }
    auto locatorAbility = DelayedSingleton<LocatorAbility>::GetInstance();
    if (locatorAbility == nullptr) {
        LBSLOGE(LOCATOR, "PreStartLocating: LocatorAbility is nullptr.");
        reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
        return ERRCODE_SERVICE_UNAVAILABLE;
    }
    std::unique_ptr<RequestConfig> requestConfig = RequestConfig::Unmarshalling(data);
    sptr<IRemoteObject> remoteObject = data.ReadRemoteObject();
    if (remoteObject == nullptr) {
        LBSLOGE(LOCATOR, "StartLocating remote object nullptr");
        reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
        return ERRCODE_SERVICE_UNAVAILABLE;
    }

    sptr<IRemoteObject::DeathRecipient> death(new (std::nothrow) LocatorCallbackDeathRecipient());
    remoteObject->AddDeathRecipient(death);
    sptr<ILocatorCallback> callback = iface_cast<ILocatorCallback>(remoteObject);
    reply.WriteInt32(locatorAbility->StartLocating(requestConfig, callback, identity));
    return ERRCODE_SUCCESS;
}

// base/location/services/location_locator/locator/source/locator_ability.cpp
LocationErrCode LocatorAbility::StartLocating(std::unique_ptr<RequestConfig>& requestConfig,
    sptr<ILocatorCallback>& callback, AppIdentity &identity)
{
#if !defined(FEATURE_GNSS_SUPPORT) && !defined(FEATURE_NETWORK_SUPPORT) && !defined(FEATURE_PASSIVE_SUPPORT)
    LBSLOGE(LOCATOR, "%{public}s: service unavailable", __func__);
    return ERRCODE_NOT_SUPPORTED;
#endif
    if (QuerySwitchState() == DISABLED) {
        ReportErrorStatus(callback, ERROR_SWITCH_UNOPEN);
    }
    if (!CheckSaValid()) {
        UpdateSaAbilityHandler();
    }
    // update offset before add request
    if (reportManager_ == nullptr || requestManager_ == nullptr) {
        return ERRCODE_SERVICE_UNAVAILABLE;
    }
    reportManager_->UpdateRandom();
    // generate request object according to input params
    std::shared_ptr<Request> request = std::make_shared<Request>();
    request->SetUid(identity.GetUid());
    request->SetPid(identity.GetPid());
    request->SetTokenId(identity.GetTokenId());
    request->SetFirstTokenId(identity.GetFirstTokenId());
    request->SetPackageName(identity.GetBundleName());
    request->SetRequestConfig(*requestConfig);
    request->SetLocatorCallBack(callback);
    request->SetUuid(std::to_string(CommonUtils::IntRandom(MIN_INT_RANDOM, MAX_INT_RANDOM)));
    LBSLOGI(LOCATOR, "start locating");
    requestManager_->HandleStartLocating(request);
    ReportLocationStatus(callback, SESSION_START);
    return ERRCODE_SUCCESS;
}

// base/location/services/location_locator/locator/source/request_manager.cpp
void RequestManager::HandleStartLocating(std::shared_ptr<Request> request)
{
    auto locatorAbility = DelayedSingleton<LocatorAbility>::GetInstance();
    auto locatorDftManager = DelayedSingleton<LocatorDftManager>::GetInstance();
    if (locatorAbility == nullptr || locatorDftManager == nullptr) {
        return;
    }
    // restore request to all request list
    bool isNewRequest = RestorRequest(request);     ---> 不存在就添加,存在一样的则更新覆盖旧的
    // update request map
    if (isNewRequest) {     // 新的需要做一些更新操作
        locatorAbility->RegisterPermissionCallback(request->GetTokenId(),
            {ACCESS_APPROXIMATELY_LOCATION, ACCESS_LOCATION, ACCESS_BACKGROUND_LOCATION});
        UpdateRequestRecord(request, true);
        UpdateUsingPermission(request);
        locatorDftManager->LocationSessionStart(request);
    }
    // process location request
    HandleRequest();       ---> 继续看位置请求
}

void RequestManager::HandleRequest()
{
    auto locatorAbility = DelayedSingleton<LocatorAbility>::GetInstance();
    if (locatorAbility == nullptr) {
        LBSLOGE(REQUEST_MANAGER, "locatorAbility is null");
        return;
    }
    std::unique_lock<std::mutex> lock(requestMutex_, std::defer_lock);
    lock.lock();
    auto requests = locatorAbility->GetRequests();
    lock.unlock();
    if (requests == nullptr) {
        LBSLOGE(REQUEST_MANAGER, "requests map is empty");
        return;
    }
    std::map<std::string, std::list<std::shared_ptr<Request>>>::iterator iter;
    for (iter = requests->begin(); iter != requests->end(); ++iter) {
        std::string abilityName = iter->first;
        std::list<std::shared_ptr<Request>> requestList = iter->second;
        HandleRequest(abilityName, requestList);
    }
}

// abilityName 是请求定位的类型,比如gnss、网络 ……等
void RequestManager::HandleRequest(std::string abilityName, std::list<std::shared_ptr<Request>> list)
{
    // generate work record, and calculate interval
    std::shared_ptr<WorkRecord> workRecord = std::make_shared<WorkRecord>();
    for (auto iter = list.begin(); iter != list.end(); iter++) {
        auto request = *iter;
        if (!AddRequestToWorkRecord(request, workRecord)) {
            continue;
        }
        if (!ActiveLocatingStrategies(request)) {
            continue;
        }
        LBSLOGD(REQUEST_MANAGER, "add pid:%{public}d uid:%{public}d %{public}s", request->GetPid(), request->GetUid(),
            request->GetPackageName().c_str());
    }
    LBSLOGD(REQUEST_MANAGER, "detect %{public}s ability requests(size:%{public}s) work record:%{public}s",
        abilityName.c_str(), std::to_string(list.size()).c_str(), workRecord->ToString().c_str());
    ProxySendLocationRequest(abilityName, *workRecord);    ---> 继续看代码
}

void RequestManager::ProxySendLocationRequest(std::string abilityName, WorkRecord& workRecord)
{
    auto locationSaLoadManager = DelayedSingleton<LocationSaLoadManager>::GetInstance();
    if (locationSaLoadManager == nullptr) {
        return;
    }
    int systemAbilityId = CommonUtils::AbilityConvertToId(abilityName);
    locationSaLoadManager->LoadLocationSa(systemAbilityId);
    sptr<IRemoteObject> remoteObject = CommonUtils::GetRemoteObject(systemAbilityId, CommonUtils::InitDeviceId());
    if (remoteObject == nullptr) {
        LBSLOGE(LOCATOR, "%{public}s: remote obj is nullptr", __func__);
        return;
    }
    workRecord.SetDeviceId(CommonUtils::InitDeviceId());
    if (abilityName == GNSS_ABILITY) {
#ifdef FEATURE_GNSS_SUPPORT
        std::unique_ptr<GnssAbilityProxy> gnssProxy = std::make_unique<GnssAbilityProxy>(remoteObject);
        gnssProxy->SendLocationRequest(workRecord);
#endif
    } else if (abilityName == NETWORK_ABILITY) {
#ifdef FEATURE_NETWORK_SUPPORT
        std::unique_ptr<NetworkAbilityProxy> networkProxy = std::make_unique<NetworkAbilityProxy>(remoteObject);
        networkProxy->SendLocationRequest(workRecord);
#endif
    } else if (abilityName == PASSIVE_ABILITY) {
#ifdef FEATURE_PASSIVE_SUPPORT
        std::unique_ptr<PassiveAbilityProxy> passiveProxy = std::make_unique<PassiveAbilityProxy>(remoteObject);
        passiveProxy->SendLocationRequest(workRecord);
#endif
    }
    auto fusionController = DelayedSingleton<FusionController>::GetInstance();
    if (fusionController != nullptr) {
        fusionController->Process(abilityName);
    }
}

上面的代码可以看到,会根据 abilityName 来确定走的是哪一个,这里假设我们是 gps,所以就会走到
gnssProxy->SendLocationRequest(workRecord);
对应看gnss里面的方法:

// base/location/services/location_locator/locator/source/gnss_ability_proxy.cpp
LocationErrCode GnssAbilityProxy::SendLocationRequest(WorkRecord &workrecord)
{
    MessageParcel data;
    MessageParcel reply;
    MessageOption option;
    if (!data.WriteInterfaceToken(GetDescriptor())) {
        LBSLOGE(GNSS, "write interfaceToken fail!");
        return ERRCODE_SERVICE_UNAVAILABLE;
    }
    workrecord.Marshalling(data);
    int error = Remote()->SendRequest(static_cast<uint32_t>(GnssInterfaceCode::SEND_LOCATION_REQUEST),
                                      data,
                                      reply,
                                      option);
    LBSLOGD(GNSS, "%{public}s Transact Error = %{public}d", __func__, error);
    return LocationErrCode(reply.ReadInt32());
}

这里其实就是把数据和参数封装,然后发送 SEND_LOCATION_REQUEST 消息给对应的SA stub 处理。

// base/location/services/location_gnss/gnss/source/gnss_ability_skeleton.cpp
int GnssAbilityStub::OnRemoteRequest(uint32_t code,
    MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
    pid_t callingPid = IPCSkeleton::GetCallingPid();
    pid_t callingUid = IPCSkeleton::GetCallingUid();
    LBSLOGI(GNSS, "OnRemoteRequest cmd = %{public}u, flags= %{public}d, pid= %{public}d, uid= %{public}d",
        code, option.GetFlags(), callingPid, callingUid);

    if (data.ReadInterfaceToken() != GetDescriptor()) {
        LBSLOGE(GNSS, "invalid token.");
        reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
        return ERRCODE_SERVICE_UNAVAILABLE;
    }

    int ret = ERRCODE_SUCCESS;
    bool isMessageRequest = false;
    switch (code) {
        case static_cast<uint32_t>(GnssInterfaceCode::SEND_LOCATION_REQUEST): // 处理 SEND_LOCATION_REQUEST 消息的地方
        case static_cast<uint32_t>(GnssInterfaceCode::SET_MOCKED_LOCATIONS): {
            if (!CommonUtils::CheckCallingPermission(callingUid, callingPid, reply)) {
                return ERRCODE_PERMISSION_DENIED;
            }
            SendMessage(code, data, reply);
            isMessageRequest = true;
            break;
        }

// base/location/services/location_gnss/gnss/source/gnss_ability.cpp
void GnssAbility::SendMessage(uint32_t code, MessageParcel &data, MessageParcel &reply)
{
    if (gnssHandler_ == nullptr) {
        reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
        return;
    }
    switch (code) {
        case static_cast<uint32_t>(GnssInterfaceCode::SEND_LOCATION_REQUEST): {
            std::unique_ptr<WorkRecord> workrecord = WorkRecord::Unmarshalling(data);
            AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::  Get(code, workrecord);
            if (gnssHandler_->SendEvent(event)) {     ---> 处理这个事件
                reply.WriteInt32(ERRCODE_SUCCESS);
            } else {
                reply.WriteInt32(ERRCODE_SERVICE_UNAVAILABLE);
            }
            break;
        }
…… …… …… …… …… …… …… …… …… …… …… …… …… …… …… …… …… ……
// 处理 SEND_LOCATION_REQUEST
void GnssHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer& event)
{
    auto gnssAbility = DelayedSingleton<GnssAbility>::GetInstance();
    if (gnssAbility == nullptr) {
        LBSLOGE(GNSS, "ProcessEvent: gnss ability is nullptr");
        return;
    }
    uint32_t eventId = event->GetInnerEventId();
    LBSLOGI(GNSS, "ProcessEvent event:%{public}d", eventId);
    switch (eventId) {
        case EVENT_REPORT_LOCATION: {
            gnssAbility->ProcessReportLocationMock();
            break;
        }
        case static_cast<uint32_t>(GnssInterfaceCode::SEND_LOCATION_REQUEST): {
            std::unique_ptr<WorkRecord> workrecord = event->GetUniqueObject<WorkRecord>();
            if (workrecord != nullptr) {
                gnssAbility->LocationRequest(*workrecord);     ---> 发送给gnss SA 处理
            }
            break;
        }

其实我们通过代码可以看到,再往下,就是通过 HDI 到驱动了,驱动再去打开硬件做相应的操作,需要看对应的平台代码。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值