/* * Copyright (C) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "locator_agent.h" #include "locationhub_ipc_interface_code.h" #include "location_sa_load_manager.h" #include "system_ability_definition.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "location_log.h" namespace OHOS { namespace Location { LocatorAgentManager* LocatorAgentManager::GetInstance() { static LocatorAgentManager data; return &data; } LocatorAgentManager::LocatorAgentManager() { nmeaCallbackHost_ = sptr(new (std::nothrow) NativeNmeaCallbackHost()); gnssCallbackHost_ = sptr(new (std::nothrow) NativeSvCallbackHost()); locationCallbackHost_ = sptr(new (std::nothrow) NativeLocationCallbackHost()); } LocatorAgentManager::~LocatorAgentManager() {} void LocatorAgentManager::StartGnssLocating(const LocationCallbackIfaces& callback) { if (locationCallbackHost_ == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return; } auto proxy = GetLocatorAgent(); if (proxy == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__); return; } locationCallbackHost_->SetCallback(callback); auto locatorCallback = sptr(locationCallbackHost_); LocationErrCode ret = proxy->StartGnssLocating(locatorCallback); LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret); } void LocatorAgentManager::StopGnssLocating() { auto proxy = GetLocatorAgent(); if (proxy == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__); return; } auto locatorCallback = sptr(locationCallbackHost_); LocationErrCode ret = proxy->StopGnssLocating(locatorCallback); LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret); } void LocatorAgentManager::RegisterGnssStatusCallback(const SvStatusCallbackIfaces& callback) { if (gnssCallbackHost_ == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return; } auto proxy = GetLocatorAgent(); if (proxy == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__); return; } gnssCallbackHost_->SetCallback(callback); auto gnssCallback = sptr(gnssCallbackHost_); LocationErrCode ret = proxy->RegisterGnssStatusCallback(gnssCallback); LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret); } void LocatorAgentManager::UnregisterGnssStatusCallback() { auto proxy = GetLocatorAgent(); if (proxy == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__); return; } auto gnssCallback = sptr(gnssCallbackHost_); LocationErrCode ret = proxy->UnregisterGnssStatusCallback(gnssCallback); LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret); } void LocatorAgentManager::RegisterNmeaMessageCallback(const GnssNmeaCallbackIfaces& callback) { if (nmeaCallbackHost_ == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return; } auto proxy = GetLocatorAgent(); if (proxy == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__); return; } nmeaCallbackHost_->SetCallback(callback); auto nmeaCallback = sptr(nmeaCallbackHost_); LocationErrCode ret = proxy->RegisterNmeaMessageCallback(nmeaCallback); LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret); } void LocatorAgentManager::UnregisterNmeaMessageCallback() { auto proxy = GetLocatorAgent(); if (proxy == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get proxy failed.", __func__); return; } auto nmeaCallback = sptr(nmeaCallbackHost_); LocationErrCode ret = proxy->UnregisterNmeaMessageCallback(nmeaCallback); LBSLOGE(LOCATOR_STANDARD, "%{public}s ret = %{public}d", __func__, ret); } sptr LocatorAgentManager::GetLocatorAgent() { std::unique_lock lock(mutex_, std::defer_lock); lock.lock(); if (client_ != nullptr) { LBSLOGI(LOCATOR_STANDARD, "%{public}s get proxy success.", __func__); lock.unlock(); return client_; } lock.unlock(); sptr saObject = CheckLocatorSystemAbilityLoaded(); return InitLocatorAgent(saObject); } bool LocatorAgentManager::TryLoadLocatorSystemAbility() { auto instance = LocationSaLoadManager::GetInstance(); if (instance == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s get instance failed.", __func__); return false; } if (instance->LoadLocationSa(LOCATION_LOCATOR_SA_ID) != ERRCODE_SUCCESS) { LBSLOGE(LOCATOR_STANDARD, "%{public}s load sa failed.", __func__); return false; } return true; } sptr LocatorAgentManager::InitLocatorAgent(sptr& saObject) { if (saObject == nullptr) { return nullptr; } std::unique_lock lock(mutex_); recipient_ = sptr(new (std::nothrow) LocatorAgentDeathRecipient(*this)); if ((saObject->IsProxyObject()) && (!saObject->AddDeathRecipient(recipient_))) { LBSLOGE(LOCATOR_STANDARD, "%{public}s: deathRecipient add failed.", __func__); return nullptr; } LBSLOGI(LOCATOR_STANDARD, "%{public}s: client reset success.", __func__); client_ = sptr(new (std::nothrow) LocatorAgent(saObject)); return client_; } sptr LocatorAgentManager::CheckLocatorSystemAbilityLoaded() { sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s: get samgr failed.", __func__); return nullptr; } sptr saObject = samgr->CheckSystemAbility(LOCATION_LOCATOR_SA_ID); if (saObject == nullptr) { if (!TryLoadLocatorSystemAbility()) { return nullptr; } saObject = samgr->CheckSystemAbility(LOCATION_LOCATOR_SA_ID); if (saObject == nullptr) { return nullptr; } } return saObject; } void LocatorAgentManager::ResetLocatorAgent(const wptr &remote) { std::unique_lock lock(mutex_); if (remote == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s: remote is nullptr.", __func__); return; } if (client_ == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s: proxy is nullptr.", __func__); return; } if (remote.promote() != nullptr) { remote.promote()->RemoveDeathRecipient(recipient_); } client_ = nullptr; } LocatorAgent::LocatorAgent(const sptr &impl) : IRemoteProxy(impl) { } LocationErrCode LocatorAgent::StartGnssLocating(sptr& callback) { if (callback == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return ERRCODE_INVALID_PARAM; } auto requestConfig = std::make_unique(); requestConfig->SetPriority(PRIORITY_FAST_FIRST_FIX); requestConfig->SetScenario(SCENE_UNSET); requestConfig->SetFixNumber(0); MessageParcel data; MessageParcel reply; data.WriteInterfaceToken(GetDescriptor()); requestConfig->Marshalling(data); data.WriteObject(callback->AsObject()); return SendRequestToStub(static_cast(LocatorInterfaceCode::START_LOCATING), data, reply); } LocationErrCode LocatorAgent::StopGnssLocating(sptr& callback) { if (callback == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return ERRCODE_INVALID_PARAM; } MessageParcel data; MessageParcel reply; data.WriteInterfaceToken(GetDescriptor()); data.WriteObject(callback->AsObject()); return SendRequestToStub(static_cast(LocatorInterfaceCode::STOP_LOCATING), data, reply); } LocationErrCode LocatorAgent::RegisterNmeaMessageCallback(const sptr& callback) { if (callback == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return ERRCODE_INVALID_PARAM; } MessageParcel data; MessageParcel reply; data.WriteInterfaceToken(GetDescriptor()); data.WriteObject(callback->AsObject()); return SendRequestToStub(static_cast(LocatorInterfaceCode::REG_NMEA_CALLBACK_V9), data, reply); } LocationErrCode LocatorAgent::UnregisterNmeaMessageCallback(const sptr& callback) { if (callback == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return ERRCODE_INVALID_PARAM; } MessageParcel data; MessageParcel reply; data.WriteInterfaceToken(GetDescriptor()); data.WriteObject(callback->AsObject()); return SendRequestToStub(static_cast(LocatorInterfaceCode::UNREG_NMEA_CALLBACK_V9), data, reply); } LocationErrCode LocatorAgent::RegisterGnssStatusCallback(const sptr& callback) { if (callback == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return ERRCODE_INVALID_PARAM; } MessageParcel data; MessageParcel reply; data.WriteInterfaceToken(GetDescriptor()); data.WriteObject(callback->AsObject()); return SendRequestToStub(static_cast(LocatorInterfaceCode::REG_GNSS_STATUS_CALLBACK), data, reply); } LocationErrCode LocatorAgent::UnregisterGnssStatusCallback(const sptr& callback) { if (callback == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s callback is nullptr", __func__); return ERRCODE_INVALID_PARAM; } MessageParcel data; MessageParcel reply; data.WriteInterfaceToken(GetDescriptor()); data.WriteObject(callback->AsObject()); return SendRequestToStub(static_cast(LocatorInterfaceCode::UNREG_GNSS_STATUS_CALLBACK), data, reply); } LocationErrCode LocatorAgent::SendRequestToStub(const int msgId, MessageParcel& data, MessageParcel& reply) { MessageOption option; sptr remote = Remote(); if (remote == nullptr) { LBSLOGE(LOCATOR_STANDARD, "%{public}s remote is null", __func__); return ERRCODE_SERVICE_UNAVAILABLE; } int error = remote->SendRequest(msgId, data, reply, option); if (error != NO_ERROR) { LBSLOGE(LOCATOR_STANDARD, "msgid = %{public}d, SendRequestToStub error: %{public}d", msgId, error); return ERRCODE_SERVICE_UNAVAILABLE; } return LocationErrCode(reply.ReadInt32()); } } }