/* * Copyright (C) 2022 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 #include #include #include #include #include #include #include "common_utils.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "system_ability_definition.h" #include "constant_definition.h" #include "parameter.h" #include "location_sa_load_manager.h" #include "hook_utils.h" #include "accesstoken_kit.h" #include "os_account_manager.h" #include "os_account_info.h" #include "permission_manager.h" #include "file_ex.h" #include namespace OHOS { namespace Location { static std::shared_ptr>> g_proxyMap = std::make_shared>>(); std::mutex g_proxyMutex; static std::random_device g_randomDevice; static std::mt19937 g_gen(g_randomDevice()); static std::uniform_int_distribution<> g_dis(0, 15); // random between 0 and 15 static std::uniform_int_distribution<> g_dis2(8, 11); // random between 8 and 11 const int32_t STOI_BYTE_LIMIT = 8; const int32_t MAX_INT_LENGTH = 9; const size_t MAX_ULL_SIZE = 19; const int64_t SEC_TO_NANO = 1000 * 1000 * 1000; const int DEFAULT_USERID = 100; int CommonUtils::AbilityConvertToId(const std::string ability) { if (GNSS_ABILITY.compare(ability) == 0) { return LOCATION_GNSS_SA_ID; } if (NETWORK_ABILITY.compare(ability) == 0) { return LOCATION_NETWORK_LOCATING_SA_ID; } if (PASSIVE_ABILITY.compare(ability) == 0) { return LOCATION_NOPOWER_LOCATING_SA_ID; } if (GEO_ABILITY.compare(ability) == 0) { return LOCATION_GEO_CONVERT_SA_ID; } return -1; } std::u16string CommonUtils::GetCapabilityToString(std::string ability, uint32_t capability) { std::string value = "{\"Capabilities\":{\"" + ability + "\":" + std::to_string(capability) + "}}"; return Str8ToStr16(value); } std::u16string CommonUtils::GetCapability(std::string ability) { uint32_t capability = 0x102; return GetCapabilityToString(ability, capability); } OHOS::HiviewDFX::HiLogLabel CommonUtils::GetLabel(std::string name) { if (GNSS_ABILITY.compare(name) == 0) { return GNSS; } if (NETWORK_ABILITY.compare(name) == 0) { return NETWORK; } if (PASSIVE_ABILITY.compare(name) == 0) { return PASSIVE; } if (GEO_ABILITY.compare(name) == 0) { return GEO_CONVERT; } OHOS::HiviewDFX::HiLogLabel label = { LOG_CORE, LOCATION_LOG_DOMAIN, "unknown" }; return label; } sptr CommonUtils::GetRemoteObject(int abilityId) { return GetRemoteObject(abilityId, InitDeviceId()); } sptr CommonUtils::GetRemoteObject(int abilityId, std::string deviceId) { std::unique_lock lock(g_proxyMutex); auto objectGnss = g_proxyMap->find(abilityId); if (objectGnss == g_proxyMap->end()) { auto manager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (manager == nullptr) { LBSLOGE(COMMON_UTILS, "GetSystemAbilityManager is null."); return nullptr; } sptr object = manager->GetSystemAbility(abilityId, deviceId); if (object == nullptr) { LBSLOGE(COMMON_UTILS, "GetSystemAbility is null."); return nullptr; } g_proxyMap->insert(std::make_pair(abilityId, object)); return object; } else { sptr remoteObject = objectGnss->second; return remoteObject; } } std::string CommonUtils::InitDeviceId() { std::string deviceId; return deviceId; } bool CommonUtils::GetActiveUserIds(std::vector& activeIds) { int ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds); if (ret != 0) { activeIds.push_back(DEFAULT_USERID); LBSLOGI(COMMON_UTILS, "GetCurrentUserId failed ret:%{public}d", ret); return false; } if (activeIds.empty()) { activeIds.push_back(DEFAULT_USERID); LBSLOGE(COMMON_UTILS, "QueryActiveOsAccountIds activeIds empty"); return false; } return true; } int CommonUtils::GetUserIdByUid(int uid) { int userId = 0; AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId); if (userId == 0) { GetCurrentUserId(userId); LBSLOGE(COMMON_UTILS, "GetUserIdByUid userId = %{public}d", userId); } return userId; } bool CommonUtils::GetCurrentUserId(int &userId) { std::vector activeIds; int ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds); if (ret != 0) { userId = DEFAULT_USERID; LBSLOGI(COMMON_UTILS, "GetCurrentUserId failed ret:%{public}d", ret); return false; } if (activeIds.empty()) { userId = DEFAULT_USERID; LBSLOGE(COMMON_UTILS, "QueryActiveOsAccountIds activeIds empty"); return false; } userId = activeIds[0]; return true; } bool CommonUtils::GetAllUserId(std::vector& activeIds) { std::vector accountInfos; int ret = AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(accountInfos); if (ret != 0) { LBSLOGE(COMMON_UTILS, "GetAllUserId failed ret:%{public}d", ret); return false; } for (auto &info : accountInfos) { activeIds.push_back(info.GetLocalId()); } if (activeIds.empty()) { LBSLOGE(COMMON_UTILS, "QueryActiveOsAccountIds activeIds empty"); return false; } return true; } void CountDownLatch::Wait(int time) { LBSLOGD(LOCATOR_STANDARD, "enter wait, time = %{public}d", time); std::unique_lock lock(mutex_); if (count_ == 0) { LBSLOGE(LOCATOR_STANDARD, "count_ = 0"); return; } condition_.wait_for(lock, std::chrono::seconds(time / MILLI_PER_SEC), [&]() {return count_ == 0;}); } void CountDownLatch::CountDown() { LBSLOGD(LOCATOR_STANDARD, "enter CountDown"); std::unique_lock lock(mutex_); int oldC = count_.load(); while (oldC > 0) { if (count_.compare_exchange_strong(oldC, oldC - 1)) { if (oldC == 1) { LBSLOGD(LOCATOR_STANDARD, "notify_all"); condition_.notify_all(); } break; } oldC = count_.load(); } } int CountDownLatch::GetCount() { std::unique_lock lock(mutex_); return count_; } void CountDownLatch::SetCount(int count) { std::unique_lock lock(mutex_); count_ = count; } std::string CommonUtils::Str16ToStr8(std::u16string str) { if (str == DEFAULT_USTRING) { return DEFAULT_STRING; } std::wstring_convert, char16_t> convert(DEFAULT_STRING); std::string result = convert.to_bytes(str); return result == DEFAULT_STRING ? "" : result; } bool CommonUtils::DoubleEqual(double a, double b) { if (fabs(a - b) < 1e-6) { return true; } else { return false; } } double CommonUtils::CalDistance(const double lat1, const double lon1, const double lat2, const double lon2) { double radLat1 = lat1 * PI / DEGREE_PI; double radLat2 = lat2 * PI / DEGREE_PI; double radLon1 = lon1 * PI / DEGREE_PI; double radLon2 = lon2 * PI / DEGREE_PI; double latDiff = radLat1 - radLat2; double lonDiff = radLon1 - radLon2; double temp = sqrt(pow(sin(latDiff / DIS_FROMLL_PARAMETER), DIS_FROMLL_PARAMETER) + cos(radLat1) * cos(radLat2) * pow(sin(lonDiff / DIS_FROMLL_PARAMETER), DIS_FROMLL_PARAMETER)); double disRad = asin(temp) * DIS_FROMLL_PARAMETER; double dis = disRad * EARTH_RADIUS; return dis; } double CommonUtils::DoubleRandom(double min, double max) { double param = 0.0; std::random_device rd; static std::uniform_real_distribution u(min, max); static std::default_random_engine e(rd()); param = u(e); return param; } int CommonUtils::IntRandom(int min, int max) { int param = 0; std::random_device rd; static std::uniform_int_distribution u(min, max); static std::default_random_engine e(rd()); param = u(e); return param; } int64_t CommonUtils::GetCurrentTime() { struct timespec times = {0, 0}; clock_gettime(CLOCK_MONOTONIC, ×); int64_t second = static_cast(times.tv_sec); return second; } int64_t CommonUtils::GetCurrentTimeMilSec() { auto now = std::chrono::system_clock::now(); auto duration = now.time_since_epoch(); auto milliSeconds = std::chrono::duration_cast(duration).count(); return milliSeconds; } int64_t CommonUtils::GetCurrentTimeStamp() { struct timeval currentTime; gettimeofday(¤tTime, nullptr); return static_cast(currentTime.tv_sec); } std::vector CommonUtils::Split(std::string str, std::string pattern) { std::vector result; str += pattern; size_t size = str.size(); size_t i = 0; while (i < size) { size_t pos = str.find(pattern, i); if (pos != std::string::npos && pos < size) { std::string s = str.substr(i, pos - i); result.push_back(s); i = pos + pattern.size() - 1; } i++; } return result; } uint8_t CommonUtils::ConvertStringToDigit(std::string str) { uint8_t res = 0; constexpr int bitWidth = 4; constexpr int numDiffForHexAlphabet = 10; for (auto ch : str) { res = res << bitWidth; if (ch >= '0' && ch <= '9') { res += (ch - '0'); } if (ch >= 'A' && ch <= 'F') { res += (ch - 'A' + numDiffForHexAlphabet); } if (ch >= 'a' && ch <= 'f') { res += (ch - 'a' + numDiffForHexAlphabet); } } return res; } bool CommonUtils::isValidInteger(const std::string& str) { if (str.empty()) { return false; } if (str.length() > MAX_INT_LENGTH) { return false; } size_t digitStartIndex = 0; if (str[0] == '-') { if (str.length() == 1) { return false; } digitStartIndex = 1; } for (size_t i = digitStartIndex; i < str.length(); i++) { if (!std::isdigit(str[i])) { return false; } } return true; } errno_t CommonUtils::GetMacArray(const std::string& strMac, uint8_t mac[MAC_LEN]) { std::vector strVec = Split(strMac, ":"); for (size_t i = 0; i < strVec.size() && i < MAC_LEN; i++) { mac[i] = ConvertStringToDigit(strVec[i]); } return EOK; } bool CommonUtils::GetStringParameter(const std::string& type, std::string& value) { char result[MAX_BUFF_SIZE] = {0}; auto res = GetParameter(type.c_str(), "", result, MAX_BUFF_SIZE); if (res <= 0) { LBSLOGE(COMMON_UTILS, "%{public}s get para value failed, res: %{public}d", __func__, res); return false; } value = result; return true; } bool CommonUtils::GetEdmPolicy(std::string& name) { return GetStringParameter(EDM_POLICY_NAME, name); } std::string CommonUtils::GenerateUuid() { std::stringstream ss; int i; ss << std::hex; for (i = 0; i < 8; i++) { // first group 8 bit for UUID ss << g_dis(g_gen); } ss << "-"; for (i = 0; i < 4; i++) { // second group 4 bit for UUID ss << g_dis(g_gen); } ss << "-4"; for (i = 0; i < 3; i++) { // third group 3 bit for UUID ss << g_dis(g_gen); } ss << "-"; ss << g_dis2(g_gen); for (i = 0; i < 3; i++) { // fourth group 3 bit for UUID ss << g_dis(g_gen); } ss << "-"; for (i = 0; i < 12; i++) { // fifth group 12 bit for UUID ss << g_dis(g_gen); }; return ss.str(); } bool CommonUtils::CheckAppForUser(int32_t uid, std::string& bundleName) { std::vector activeIds; if (!CommonUtils::GetActiveUserIds(activeIds)) { LBSLOGE(COMMON_UTILS, "Fail to GetActiveUserIds"); } return CommonUtils::CheckAppForUsers(uid, activeIds, bundleName); } bool CommonUtils::CheckAppForUsers(int32_t uid, std::vector activeIds, std::string& bundleName) { int userId = 0; AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId); bool containsActiveId = std::find(activeIds.begin(), activeIds.end(), userId) != activeIds.end(); if (containsActiveId || userId == 0) { return true; } return false; } int64_t CommonUtils::GetSinceBootTime() { int result; struct timespec ts; result = clock_gettime(CLOCK_BOOTTIME, &ts); if (result == 0) { return ts.tv_sec * SEC_TO_NANO + ts.tv_nsec; } else { return 0; } } bool CommonUtils::GetConfigFromJson(const std::string &key, std::string &value) { std::string content; if (!LoadStringFromFile(LOCATION_SERVICE_CONFIG_PATH, content) || content.empty()) { LBSLOGE(COMMON_UTILS, "Fail to Load json file."); return false; } cJSON *json = cJSON_Parse(content.c_str()); if (json == nullptr) { LBSLOGE(COMMON_UTILS, "json is nullptr."); return false; } if (!cJSON_IsObject(json)) { LBSLOGE(COMMON_UTILS, "reader is not cJSON object."); cJSON_Delete(json); return false; } cJSON *cJsonObject = cJSON_GetObjectItem(json, key.c_str()); if (cJsonObject == nullptr) { LBSLOGE(COMMON_UTILS, "cJsonObject is nullptr."); cJSON_Delete(json); return false; } value = cJSON_GetStringValue(cJsonObject); cJSON_Delete(json); return true; } bool CommonUtils::IsAppBelongActiveAccounts(AppIdentity &identity, std::vector activeIds) { std::string bundleName = identity.GetBundleName(); if (CommonUtils::CheckAppForUsers(identity.GetUid(), activeIds, bundleName)) { return true; } if (PermissionManager::CheckIsSystemSa(identity.GetTokenId())) { return true; } return false; } bool CommonUtils::IsAppBelongCurrentAccount(AppIdentity &identity) { std::vector activeIds; if (!CommonUtils::GetActiveUserIds(activeIds)) { LBSLOGE(COMMON_UTILS, "Fail to GetCurrentUserId."); } return CommonUtils::IsAppBelongActiveAccounts(identity, activeIds); } bool CommonUtils::IsValidForStoull(const std::string input, size_t size) { if (size > MAX_ULL_SIZE) { return false; // 设定的最大位数大于uint64最大位数 } if (input.size() > size) { return false; // 大于设定的最大位数 } if (input.empty()) { return false; // 字符串为空 } for (char c : input) { if (!std::isdigit(c)) { return false; // 检查是否全为数字 } } return true; } LocationErrCode CommonUtils::ErrCodeToLocationErrCode(ErrCode errorCode) { LocationErrCode locationErrCode = ERRCODE_SERVICE_UNAVAILABLE; if (errorCode == ERRCODE_SUCCESS || errorCode >= ERRCODE_SERVICE_UNAVAILABLE) { locationErrCode = static_cast(errorCode); } else if (errorCode > LOCATION_ERRCODE_MIN) { locationErrCode = static_cast(errorCode - LOCATION_ERRCODE_MIN); } else { locationErrCode = ERRCODE_SERVICE_UNAVAILABLE; } return locationErrCode; } bool CommonUtils::IsStrValidForStoi(const std::string &str) { if (str.length() > STOI_BYTE_LIMIT) { return false; } return !str.empty() && std::all_of(str.begin(), str.end(), ::isdigit); } bool CommonUtils::IsExistFile(const std::string& filename) { bool bExist = false; std::fstream ioFile; char path[PATH_MAX + 1] = {0x00}; if (strlen(filename.c_str()) > PATH_MAX || realpath(filename.c_str(), path) == NULL) { LBSLOGI(GNSS, "IsExistFile false,realpath fail"); return false; } ioFile.open(path, std::ios::in); if (ioFile) { bExist = true; } else { LBSLOGI(GNSS, "IsExistFile false,open fail"); return false; } ioFile.clear(); ioFile.close(); LBSLOGI(GNSS, "IsExistFile = %{public}d", bExist ? 1 : 0); return bExist; } bool CommonUtils::CreateFile(const std::string& filename, const std::string& filedata) { std::ofstream outFile; outFile.open(filename.c_str()); if (!outFile) { LBSLOGE(GNSS, "file open failed"); return false; } outFile.flush(); outFile << filedata << std::endl; outFile.clear(); outFile.close(); LBSLOGI(GNSS, "CreateFile success"); return true; } bool CommonUtils::ConvertStringToDigit(const std::string& str, int32_t &ret) { std::from_chars_result res = std::from_chars(str.data(), str.data() + str.size(), ret); if (res.ec != std::errc{} || res.ptr != str.data() + str.size ()) { LBSLOGI(GNSS, "FromString failed, error string is %{public}s", str.c_str()); return false; } return true; } std::string CommonUtils::GetErrorMsgByCode(int code) { static std::map errorCodeMap = GetErrorCodeMap(); auto iter = errorCodeMap.find(code); if (iter != errorCodeMap.end()) { std::string errMessage = "BussinessError "; code = ConvertErrorCode(code); errMessage.append(std::to_string(code)).append(": ").append(iter->second); return errMessage; } return "undefined error."; } std::map CommonUtils::GetErrorCodeMap() { std::map errorCodeMap = { {SUCCESS, "SUCCESS"}, {NOT_SUPPORTED, "NOT_SUPPORTED"}, {INPUT_PARAMS_ERROR, "INPUT_PARAMS_ERROR"}, {REVERSE_GEOCODE_ERROR, "REVERSE_GEOCODE_ERROR"}, {GEOCODE_ERROR, "GEOCODE_ERROR"}, {LOCATOR_ERROR, "LOCATOR_ERROR"}, {LOCATION_SWITCH_ERROR, "LOCATION_SWITCH_ERROR"}, {LAST_KNOWN_LOCATION_ERROR, "LAST_KNOWN_LOCATION_ERROR"}, {LOCATION_REQUEST_TIMEOUT_ERROR, "LOCATION_REQUEST_TIMEOUT_ERROR"}, {QUERY_COUNTRY_CODE_ERROR, "QUERY_COUNTRY_CODE_ERROR"}, {LocationErrCode::ERRCODE_SUCCESS, "SUCCESS."}, {LocationErrCode::ERRCODE_PERMISSION_DENIED, "Permission verification failed. The application does not have the permission required to call the API."}, {LocationErrCode::ERRCODE_SYSTEM_PERMISSION_DENIED, "Permission verification failed. A non-system application calls a system API."}, {LocationErrCode::ERRCODE_INVALID_PARAM, "Parameter error. Possible causes:1.Mandatory parameters are left unspecified;" \ "2.Incorrect parameter types;3. Parameter verification failed."}, {LocationErrCode::ERRCODE_NOT_SUPPORTED, "Capability not supported." \ "Failed to call function due to limited device capabilities."}, {LocationErrCode::ERRCODE_SERVICE_UNAVAILABLE, "The location service is unavailable."}, {LocationErrCode::ERRCODE_LOCATING_NETWORK_FAIL, "The network locating is failed because the network cannot be accessed."}, {LocationErrCode::ERRCODE_LOCATING_ACC_FAIL, "The positioning result does not meet the precision requirement (maxAccuracy)" \ " in the positioning request parameters. "}, {LocationErrCode::ERRCODE_LOCATING_CACHE_FAIL, "The system does not have a cache locaiton."}, {LocationErrCode::ERRCODE_SWITCH_OFF, "The location switch is off."}, {LocationErrCode::ERRCODE_LOCATING_FAIL, "Failed to obtain the geographical location."}, {LocationErrCode::ERRCODE_REVERSE_GEOCODING_FAIL, "Reverse geocoding query failed."}, {LocationErrCode::ERRCODE_GEOCODING_FAIL, "Geocoding query failed."}, {LocationErrCode::ERRCODE_COUNTRYCODE_FAIL, "Failed to query the area information."}, {LocationErrCode::ERRCODE_GEOFENCE_FAIL, "Failed to operate the geofence."}, {LocationErrCode::ERRCODE_NO_RESPONSE, "No response to the request."}, {LocationErrCode::ERRCODE_GEOFENCE_EXCEED_MAXIMUM, "The number of geofences exceeds the maximum."}, {LocationErrCode::ERRCODE_GEOFENCE_INCORRECT_ID, "Failed to delete a geofence due to an incorrect ID."}, {LocationErrCode::ERRCODE_WIFI_IS_NOT_CONNECTED, "Failed to obtain the hotpot MAC address because the Wi-Fi is not connected."}, {LocationErrCode::ERRCODE_SCAN_FAIL, "Failed to start WiFi or Bluetooth scanning."}, {LocationErrCode::ERRCODE_WIFI_SCAN_FAIL, "Failed to start WiFi scanning."}, {LocationErrCode::ERRCODE_CELL_SCAN_FAIL, "Failed to start Cell scanning."} }; GetErrorCodeMapExt(errorCodeMap); return errorCodeMap; } void CommonUtils::GetErrorCodeMapExt(std::map& errorCodeMap) { errorCodeMap.insert(std::make_pair(LocationErrCode::ERRCODE_BEACONFENCE_LOCATION_SWITCH_OFF, "Failed to add a beacon fence because the location switch is off.")); errorCodeMap.insert(std::make_pair(LocationErrCode::ERRCODE_BEACONFENCE_BLUETOOTH_SWITCH_OFF, "Failed to add a beacon fence because the bluetooth switch is off.")); errorCodeMap.insert(std::make_pair(LocationErrCode::ERRCODE_BEACONFENCE_EXCEED_MAXIMUM, "The number of beacon fence exceeds the maximum.")); errorCodeMap.insert(std::make_pair(LocationErrCode::ERRCODE_BEACONFENCE_INCORRECT_ID, "Failed to delete the fence due to incorrect beacon fence information.")); errorCodeMap.insert(std::make_pair(LocationErrCode::ERRCODE_BEACONFENCE_DUPLICATE_INFORMATION, "Duplicate beacon fence information.")); } int CommonUtils::ConvertErrorCode(int errorCode) { if (errorCode == LocationErrCode::ERRCODE_LOCATING_NETWORK_FAIL || errorCode == LocationErrCode::ERRCODE_LOCATING_CACHE_FAIL || errorCode == LocationErrCode::ERRCODE_LOCATING_ACC_FAIL) { LBSLOGI(LOCATOR_STANDARD, "Convert ErrorCode: %{public}d to %{public}d", errorCode, LocationErrCode::ERRCODE_LOCATING_FAIL); return LocationErrCode::ERRCODE_LOCATING_FAIL; } if (errorCode == LocationErrCode::ERRCODE_WIFI_SCAN_FAIL || errorCode == LocationErrCode::ERRCODE_CELL_SCAN_FAIL) { return LocationErrCode::ERRCODE_SCAN_FAIL; } return errorCode; } } // namespace Location } // namespace OHOS