* 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 "location_proxy_adapter_impl.h"
#include <dlfcn.h>
#include "common_utils.h"
#include "constant_definition.h"
#include "location_adapter.h"
#include "location_callback_adapter_impl.h"
#include "nweb_log.h"
using namespace OHOS::Location;
namespace {
#if defined (__aarch64__) || defined (__x86_64__)
const std::string NWEB_WRAPPER_SO_PATH = "/system/lib64/libnweb_ohos_wrapper.z.so";
const std::string ARKWEB_WRAPPER_SO_PATH = "/system/lib64/libarkweb_os_wrapper.z.so";
#else
const std::string NWEB_WRAPPER_SO_PATH = "/system/lib/libnweb_ohos_wrapper.z.so";
const std::string ARKWEB_WRAPPER_SO_PATH = "/system/lib/libarkweb_os_wrapper.z.so";
#endif
int32_t ConvertScenario(int32_t scenario)
{
int32_t ret = OHOS::Location::SCENE_UNSET;
switch (scenario) {
case OHOS::NWeb::LocationRequestConfig::Scenario::UNSET:
ret = OHOS::Location::SCENE_UNSET;
break;
case OHOS::NWeb::LocationRequestConfig::Scenario::NAVIGATION:
ret = OHOS::Location::SCENE_NAVIGATION;
break;
case OHOS::NWeb::LocationRequestConfig::Scenario::TRAJECTORY_TRACKING:
ret = OHOS::Location::SCENE_TRAJECTORY_TRACKING;
break;
case OHOS::NWeb::LocationRequestConfig::Scenario::CAR_HAILING:
ret = OHOS::Location::SCENE_CAR_HAILING;
break;
case OHOS::NWeb::LocationRequestConfig::Scenario::DAILY_LIFE_SERVICE:
ret = OHOS::Location::SCENE_DAILY_LIFE_SERVICE;
break;
case OHOS::NWeb::LocationRequestConfig::Scenario::NO_POWER:
ret = OHOS::Location::SCENE_NO_POWER;
break;
default:
ret = OHOS::Location::SCENE_UNSET;
break;
}
return ret;
}
int32_t ConvertPriority(int32_t priority)
{
int32_t ret = OHOS::Location::PRIORITY_UNSET;
switch (priority) {
case OHOS::NWeb::LocationRequestConfig::Priority::PRIORITY_UNSET:
ret = OHOS::Location::PRIORITY_UNSET;
break;
case OHOS::NWeb::LocationRequestConfig::Priority::PRIORITY_ACCURACY:
ret = OHOS::Location::PRIORITY_ACCURACY;
break;
case OHOS::NWeb::LocationRequestConfig::Priority::PRIORITY_LOW_POWER:
ret = OHOS::Location::PRIORITY_LOW_POWER;
break;
case OHOS::NWeb::LocationRequestConfig::Priority::PRIORITY_FAST_FIRST_FIX:
ret = OHOS::Location::PRIORITY_FAST_FIRST_FIX;
break;
default:
ret = OHOS::Location::PRIORITY_UNSET;
break;
}
return ret;
}
}
namespace OHOS::NWeb {
LocationRequestConfigImpl::LocationRequestConfigImpl()
{
config_ = std::make_unique<OHOS::Location::RequestConfig>();
}
void LocationRequestConfigImpl::SetScenario(int32_t scenario)
{
if (config_ == nullptr) {
return;
}
config_->SetScenario(ConvertScenario(scenario));
}
void LocationRequestConfigImpl::SetFixNumber(int32_t number)
{
if (config_ == nullptr) {
return;
}
config_->SetFixNumber(number);
}
void LocationRequestConfigImpl::SetMaxAccuracy(int32_t maxAccuary)
{
if (config_ == nullptr) {
return;
}
config_->SetMaxAccuracy(maxAccuary);
}
void LocationRequestConfigImpl::SetDistanceInterval(int32_t disInterval)
{
if (config_ == nullptr) {
return;
}
config_->SetDistanceInterval(disInterval);
}
void LocationRequestConfigImpl::SetTimeInterval(int32_t timeInterval)
{
if (config_ == nullptr) {
return;
}
config_->SetTimeInterval(timeInterval);
}
void LocationRequestConfigImpl::SetPriority(int32_t priority)
{
if (config_ == nullptr) {
return;
}
config_->SetPriority(ConvertPriority(priority));
}
std::unique_ptr<OHOS::Location::RequestConfig>& LocationRequestConfigImpl::GetConfig()
{
return config_;
}
LocationInfoImpl::LocationInfoImpl(std::unique_ptr<OHOS::Location::Location>& location)
: location_(std::move(location)) {}
double LocationInfoImpl::GetLatitude()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetLatitude();
}
double LocationInfoImpl::GetLongitude()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetLongitude();
}
double LocationInfoImpl::GetAltitude()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetAltitude();
}
float LocationInfoImpl::GetAccuracy()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetAccuracy();
}
float LocationInfoImpl::GetSpeed()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetSpeed();
}
double LocationInfoImpl::GetDirection()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetDirection();
}
int64_t LocationInfoImpl::GetTimeStamp()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetTimeStamp();
}
int64_t LocationInfoImpl::GetTimeSinceBoot()
{
if (location_ == nullptr) {
return 0;
}
return location_->GetTimeSinceBoot();
}
std::vector<std::string> LocationInfoImpl::GetAdditions()
{
if (location_ == nullptr) {
std::vector<std::string> emptyLoc;
return emptyLoc;
}
return location_->GetAdditions();
}
std::unique_ptr<OHOS::Location::Location>& LocationInfoImpl::GetLocation()
{
return location_;
}
void* LocationProxyAdapterImpl::wrapperHandle_;
IsEnableLocationFuncType LocationProxyAdapterImpl::isEnableLocationFunc_;
EnableAbilityFuncType LocationProxyAdapterImpl::enableAbilityFunc_;
StartLocatingFuncType LocationProxyAdapterImpl::startLocatingFunc_;
StopLocatingFuncType LocationProxyAdapterImpl::stopLocatingFunc_;
LocationProxyAdapterImpl::LocationProxyAdapterImpl()
{
if (!wrapperHandle_) {
wrapperHandle_ = dlopen(ARKWEB_WRAPPER_SO_PATH.c_str(), RTLD_NOW | RTLD_GLOBAL);
}
if (!wrapperHandle_) {
wrapperHandle_ = dlopen(NWEB_WRAPPER_SO_PATH.c_str(), RTLD_NOW | RTLD_GLOBAL);
}
if (wrapperHandle_) {
if (!isEnableLocationFunc_) {
isEnableLocationFunc_ = reinterpret_cast<IsEnableLocationFuncType>(
dlsym(wrapperHandle_, "IsLocationEnable"));
}
if (!enableAbilityFunc_) {
enableAbilityFunc_ = reinterpret_cast<EnableAbilityFuncType>(
dlsym(wrapperHandle_, "EnableAbility"));
}
if (!startLocatingFunc_) {
startLocatingFunc_ = reinterpret_cast<StartLocatingFuncType>(
dlsym(wrapperHandle_, "StartLocating"));
}
if (!stopLocatingFunc_) {
stopLocatingFunc_ = reinterpret_cast<StopLocatingFuncType>(
dlsym(wrapperHandle_, "StopLocating"));
}
}
}
int32_t LocationProxyAdapterImpl::StartLocating(
std::shared_ptr<LocationRequestConfig> requestConfig,
std::shared_ptr<LocationCallbackAdapter> callback)
{
std::lock_guard<std::mutex> lock(locating_mutex_);
static int32_t count = 0;
int32_t id = -1;
if (!startLocatingFunc_ || !callback || !requestConfig) {
WVLOG_E("get Locator::GetInstance() failed or callback/requestConfig is nullptr");
return -1;
}
sptr<OHOS::Location::ILocatorCallback> iCallback =
sptr<OHOS::Location::ILocatorCallback>(new LocationCallbackImpl(callback));
id = count++;
if (count < 0) {
count = 0;
}
auto res = reg_.insert(std::make_pair(id, iCallback));
if (!res.second) {
WVLOG_E("StartLocating callback exist, id:%{public}d, reg size:%{public}zu", id, reg_.size());
return -1;
}
bool ret = startLocatingFunc_(
reinterpret_cast<LocationRequestConfigImpl*>(requestConfig.get())->GetConfig(),
iCallback);
if (!ret) {
WVLOG_E("StartLocating failed, id:%{public}d", id);
reg_.erase(id);
return -1;
}
return id;
}
bool LocationProxyAdapterImpl::StopLocating(int32_t callbackId)
{
std::lock_guard<std::mutex> lock(locating_mutex_);
if (!stopLocatingFunc_ || callbackId < 0) {
WVLOG_E("get Locator::GetInstance() failed or callback is null");
return false;
}
LocatorCallbackMap::iterator iter = reg_.find(callbackId);
if (iter == reg_.end()) {
WVLOG_E("StopLocating failed due to reg_ not find iCallback");
return false;
}
bool ret = stopLocatingFunc_(iter->second);
reg_.erase(iter);
return ret;
}
bool LocationProxyAdapterImpl::EnableAbility(bool isEnabled)
{
if (!enableAbilityFunc_) {
WVLOG_E("get Locator::GetInstance() failed");
return false;
}
return enableAbilityFunc_(isEnabled);
}
bool LocationProxyAdapterImpl::IsLocationEnabled()
{
if (!isEnableLocationFunc_) {
WVLOG_E("get Locator::GetInstance() failed");
return false;
}
bool isEnabled = false;
return isEnableLocationFunc_(isEnabled) ? isEnabled : false;
}
}