1/* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "parse_util.h" 17 18#include <cinttypes> 19#include <dlfcn.h> 20#include <fstream> 21#include <unistd.h> 22#include <memory> 23#include <sstream> 24#include <vector> 25#include <algorithm> 26 27#include "datetime_ex.h" 28#include "hisysevent_adapter.h" 29#include "hitrace_meter.h" 30#include "sam_log.h" 31#include "string_ex.h" 32#include "samgr_xcollie.h" 33 34namespace OHOS { 35using std::string; 36 37namespace { 38constexpr const char* EVENT_TYPE = "eventId"; 39constexpr const char* EVENT_NAME = "name"; 40constexpr const char* EVENT_VALUE = "value"; 41constexpr const char* SA_TAG_SYSTEM_ABILITY = "systemability"; 42constexpr const char* SA_TAG_PROCESS = "process"; 43constexpr const char* SA_TAG_LIB_PATH = "libpath"; 44constexpr const char* SA_TAG_NAME = "name"; 45constexpr const char* SA_TAG_DEPEND = "depend"; 46constexpr const char* SA_TAG_DEPEND_TIMEOUT = "depend-time-out"; 47constexpr const char* SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY = "depend_time_out"; 48constexpr const char* SA_TAG_RUN_ON_CREATE = "run-on-create"; 49constexpr const char* SA_TAG_MODULE_UPDATE = "module-update"; 50constexpr const char* SA_TAG_AUTO_RESTART = "auto-restart"; 51constexpr const char* SA_TAG_DISTRIBUTED = "distributed"; 52constexpr const char* SA_TAG_CACHE_COMMON_EVENT = "cache-common-event"; 53constexpr const char* SA_TAG_DUMP_LEVEL = "dump-level"; 54constexpr const char* SA_TAG_CAPABILITY = "capability"; 55constexpr const char* SA_TAG_PERMISSION = "permission"; 56constexpr const char* SA_TAG_BOOT_PHASE = "bootphase"; 57constexpr const char* SA_TAG_SAID = "said"; 58constexpr const char* SA_TAG_START_ON_DEMAND = "start-on-demand"; 59constexpr const char* SA_TAG_STOP_ON_DEMAND = "stop-on-demand"; 60constexpr const char* SA_TAG_ALLOW_UPDATE = "allow-update"; 61constexpr const char* SA_TAG_RECYCLE_DELAYTIME = "recycle-delaytime"; 62constexpr const char* SA_TAG_DEVICE_ON_LINE = "deviceonline"; 63constexpr const char* SA_TAG_SETTING_SWITCH = "settingswitch"; 64constexpr const char* SA_TAG_COMMON_EVENT = "commonevent"; 65constexpr const char* SA_TAG_PARAM = "param"; 66constexpr const char* SA_TAG_TIEMD_EVENT = "timedevent"; 67constexpr const char* SA_TAG_RECYCLE_STRATEGY = "recycle-strategy"; 68constexpr const char* SA_TAG_EXTENSION = "extension"; 69constexpr const char* SA_TAG_UNREF_UNLOAD = "unreferenced-unload"; 70constexpr const char* SA_TAG_LONGTIMEUNUSED_UNLOAD = "longtimeunused-unload"; 71constexpr int32_t MAX_JSON_OBJECT_SIZE = 50 * 1024; 72constexpr int32_t MAX_JSON_STRING_LENGTH = 128; 73constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000000; 74constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff; 75constexpr int32_t MAX_EXTENSIONO_NUM = 100; 76constexpr int32_t MAX_DLOPEN_SECONDS = 60; 77constexpr const char* BOOT_START_PHASE = "BootStartPhase"; 78constexpr const char* CORE_START_PHASE = "CoreStartPhase"; 79constexpr const char* HIGH_LOAD_PRIORITY = "HighPriority"; 80constexpr const char* MEDIUM_LOAD_PRIORITY = "MediumPriority"; 81 82enum { 83 BOOT_START = 1, 84 CORE_START = 2, 85 OTHER_START = 3, 86}; 87 88enum { 89 EQ = 1, 90 GREATER_EQ = 2, 91 GREATER = 3, 92 LESS_EQ = 4, 93 LESS = 5 94}; 95} 96 97ParseUtil::~ParseUtil() 98{ 99 ClearResource(); 100} 101 102void ParseUtil::CloseHandle(SaProfile& saProfile) 103{ 104 if (saProfile.handle == nullptr) { 105 return; 106 } 107 int32_t ret = dlclose(saProfile.handle); 108 if (ret) { 109 HILOGW("close handle failed with errno:%{public}d!", errno); 110 } 111 saProfile.handle = nullptr; 112} 113 114void ParseUtil::CloseSo() 115{ 116 for (auto& saProfile : saProfiles_) { 117 CloseHandle(saProfile); 118 } 119} 120 121void ParseUtil::CloseSo(int32_t systemAbilityId) 122{ 123 for (auto& saProfile : saProfiles_) { 124 if (saProfile.saId == systemAbilityId) { 125 CloseHandle(saProfile); 126 break; 127 } 128 } 129} 130 131void ParseUtil::ClearResource() 132{ 133 CloseSo(); 134 saProfiles_.clear(); 135} 136 137void ParseUtil::OpenSo(uint32_t bootPhase) 138{ 139 for (auto& saProfile : saProfiles_) { 140 if (saProfile.runOnCreate && saProfile.bootPhase == bootPhase) { 141 OpenSo(saProfile); 142 } 143 } 144} 145 146void ParseUtil::OpenSo(SaProfile& saProfile) 147{ 148 if (saProfile.handle == nullptr) { 149 string dlopenTag = ToString(saProfile.saId) + "_DLOPEN"; 150 HITRACE_METER_NAME(HITRACE_TAG_SAMGR, dlopenTag); 151 int64_t begin = GetTickCount(); 152 DlHandle handle = nullptr; 153 if (saProfile.runOnCreate) { 154 handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW); 155 } else { 156 SamgrXCollie samgrXCollie("safwk--openso_" + ToString(saProfile.saId), MAX_DLOPEN_SECONDS); 157 handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW); 158 } 159 int64_t duration = GetTickCount() - begin; 160 ReportSaLoadDuration(saProfile.saId, SA_LOAD_OPENSO, duration); 161 KHILOGI("SA:%{public}d OpenSo spend %{public}" PRId64 "ms", 162 saProfile.saId, duration); 163 if (handle == nullptr) { 164 std::vector<string> libPathVec; 165 string fileName = ""; 166 SplitStr(saProfile.libPath, "/", libPathVec); 167 if (libPathVec.size() > 0) { 168 fileName = libPathVec[libPathVec.size() - 1]; 169 } 170 ReportAddSystemAbilityFailed(saProfile.saId, getpid(), getuid(), fileName); 171 HILOGE("SA:%{public}d dlopen %{public}s failed with errno:%{public}s!", 172 saProfile.saId, fileName.c_str(), dlerror()); 173 return; 174 } 175 saProfile.handle = handle; 176 } else { 177 KHILOGI("SA:%{public}d handle is not null", saProfile.saId); 178 } 179} 180 181bool ParseUtil::LoadSaLib(int32_t systemAbilityId) 182{ 183 for (auto& saProfile : saProfiles_) { 184 if (saProfile.saId == systemAbilityId) { 185 OpenSo(saProfile); 186 return true; 187 } 188 } 189 return false; 190} 191 192const std::list<SaProfile>& ParseUtil::GetAllSaProfiles() const 193{ 194 return saProfiles_; 195} 196 197bool ParseUtil::GetProfile(int32_t saId, SaProfile& saProfile) 198{ 199 auto iter = std::find_if(saProfiles_.begin(), saProfiles_.end(), [saId](auto saProfile) { 200 return saProfile.saId == saId; 201 }); 202 if (iter != saProfiles_.end()) { 203 saProfile = *iter; 204 return true; 205 } 206 return false; 207} 208 209void ParseUtil::RemoveSaProfile(int32_t saId) 210{ 211 saProfiles_.remove_if([saId] (auto saInfo) -> bool { return saInfo.saId == saId; }); 212} 213 214uint32_t ParseUtil::GetBootPriorityPara(const std::string& bootPhase) 215{ 216 if (bootPhase == BOOT_START_PHASE) { 217 return static_cast<uint32_t>(BOOT_START); 218 } else if (bootPhase == CORE_START_PHASE) { 219 return static_cast<uint32_t>(CORE_START); 220 } else { 221 return static_cast<uint32_t>(OTHER_START); 222 } 223} 224 225uint32_t ParseUtil::GetOndemandPriorityPara(const std::string& loadPriority) 226{ 227 if (loadPriority == HIGH_LOAD_PRIORITY) { 228 return static_cast<uint32_t>(HIGH_PRIORITY); 229 } else if (loadPriority == MEDIUM_LOAD_PRIORITY) { 230 return static_cast<uint32_t>(MEDIUM_PRIORITY); 231 } else { 232 return static_cast<uint32_t>(LOW_PRIORITY); 233 } 234} 235 236bool ParseUtil::ParseSaProfiles(const string& profilePath) 237{ 238 HILOGD("profilePath:%{private}s", profilePath.c_str()); 239 string realPath = GetRealPath(profilePath); 240 if (!CheckPathExist(realPath.c_str())) { 241 HILOGE("bad profile path!"); 242 return false; 243 } 244 245 if (Endswith(realPath, ".json")) { 246 return ParseJsonFile(realPath); 247 } else { 248 HILOGE("Invalid file format, please use json file!"); 249 return false; 250 } 251} 252 253bool ParseUtil::Endswith(const std::string& src, const std::string& sub) 254{ 255 return (src.length() >= sub.length() && (src.rfind(sub) == (src.length() - sub.length()))); 256} 257 258std::unordered_map<std::string, std::string> ParseUtil::StringToMap(const std::string& eventStr) 259{ 260 nlohmann::json eventJson = StringToJsonObj(eventStr); 261 std::unordered_map<std::string, std::string> eventMap = JsonObjToMap(eventJson); 262 return eventMap; 263} 264 265nlohmann::json ParseUtil::StringToJsonObj(const std::string& eventStr) 266{ 267 nlohmann::json jsonObj = nlohmann::json::object(); 268 if (eventStr.empty()) { 269 return jsonObj; 270 } 271 nlohmann::json eventJson = nlohmann::json::parse(eventStr, nullptr, false); 272 if (eventJson.is_discarded()) { 273 HILOGE("parse eventStr to json failed"); 274 return jsonObj; 275 } 276 if (!eventJson.is_object()) { 277 HILOGE("eventStr converted result is not a jsonObj"); 278 return jsonObj; 279 } 280 return eventJson; 281} 282 283std::unordered_map<std::string, std::string> ParseUtil::JsonObjToMap(const nlohmann::json& eventJson) 284{ 285 std::unordered_map<std::string, std::string> eventMap; 286 if (eventJson.contains(EVENT_TYPE) && eventJson[EVENT_TYPE].is_string()) { 287 eventMap[EVENT_TYPE] = eventJson[EVENT_TYPE]; 288 } else { 289 eventMap[EVENT_TYPE] = ""; 290 } 291 if (eventJson.contains(EVENT_NAME) && eventJson[EVENT_NAME].is_string()) { 292 eventMap[EVENT_NAME] = eventJson[EVENT_NAME]; 293 } else { 294 eventMap[EVENT_NAME] = ""; 295 } 296 if (eventJson.contains(EVENT_VALUE) && eventJson[EVENT_VALUE].is_string()) { 297 eventMap[EVENT_VALUE] = eventJson[EVENT_VALUE]; 298 } else { 299 eventMap[EVENT_VALUE] = ""; 300 } 301 return eventMap; 302} 303 304bool ParseUtil::ParseJsonFile(const string& realPath) 305{ 306 nlohmann::json profileJson; 307 bool result = ParseJsonObj(profileJson, realPath); 308 if (!result) { 309 HILOGE("json file parse error!"); 310 return false; 311 } 312 HILOGD("profileJson:%{private}s", profileJson.dump().c_str()); 313 string process; 314 GetStringFromJson(profileJson, SA_TAG_PROCESS, process); 315 if (process.empty()) { 316 HILOGE("profile format error: no process tag"); 317 return false; 318 } 319 if (process.length() > MAX_JSON_STRING_LENGTH) { 320 HILOGE("profile format error: process is too long"); 321 return false; 322 } 323 procName_ = Str8ToStr16(process); 324 if (profileJson.find(SA_TAG_SYSTEM_ABILITY) == profileJson.end()) { 325 HILOGE("system ability parse error!"); 326 return false; 327 } 328 nlohmann::json& systemAbilityJson = profileJson.at(SA_TAG_SYSTEM_ABILITY); 329 HILOGD("systemAbilityJson:%{private}s", systemAbilityJson.dump().c_str()); 330 if (!systemAbilityJson.is_array()) { 331 HILOGE("system ability is not array!"); 332 return false; 333 } 334 size_t size = systemAbilityJson.size(); 335 for (size_t i = 0; i < size; i++) { 336 SaProfile saProfile = { procName_ }; 337 if (!ParseSystemAbility(saProfile, systemAbilityJson[i])) { 338 continue; 339 } 340 saProfiles_.emplace_back(saProfile); 341 } 342 return !saProfiles_.empty(); 343} 344 345bool ParseUtil::ParseSystemAbilityGetExtension(SaProfile& saProfile, nlohmann::json& systemAbilityJson) 346{ 347 if ((systemAbilityJson.find(SA_TAG_EXTENSION) != systemAbilityJson.end()) && 348 (systemAbilityJson[SA_TAG_EXTENSION].is_array())) { 349 for (auto& item : systemAbilityJson[SA_TAG_EXTENSION]) { 350 std::string extension = item.get<std::string>(); 351 if (extension.length() > MAX_JSON_STRING_LENGTH) { 352 HILOGE("profile format error: extension() len exceed limit"); 353 return false; 354 } 355 if (saProfile.extension.size() >= MAX_EXTENSIONO_NUM) { 356 HILOGE("profile format error: extension num exceed limit"); 357 return false; 358 } 359 360 if (std::find(saProfile.extension.begin(), saProfile.extension.end(), extension) == 361 saProfile.extension.end()) { 362 saProfile.extension.push_back(extension); 363 } 364 } 365 } 366 return true; 367} 368 369bool ParseUtil::ParseSystemAbilityGetSaBaseInfo(SaProfile& saProfile, nlohmann::json& systemAbilityJson) 370{ 371 GetInt32FromJson(systemAbilityJson, SA_TAG_NAME, saProfile.saId); 372 if (saProfile.saId == 0) { 373 HILOGE("profile format error: no name tag"); 374 return false; 375 } 376 if (saProfile.saId < FIRST_SYS_ABILITY_ID || saProfile.saId > LAST_SYS_ABILITY_ID) { 377 HILOGE("profile format error: saId error"); 378 return false; 379 } 380 GetStringFromJson(systemAbilityJson, SA_TAG_LIB_PATH, saProfile.libPath); 381 if (saProfile.libPath.empty()) { 382 HILOGE("profile format error: no libPath tag"); 383 return false; 384 } 385 if (saProfile.libPath.length() > MAX_JSON_STRING_LENGTH) { 386 HILOGE("profile format error: libPath is too long"); 387 return false; 388 } 389 return true; 390} 391 392bool ParseUtil::ParseSystemAbilityGetSaExtInfo(SaProfile& saProfile, nlohmann::json& systemAbilityJson) 393{ 394 GetBoolFromJson(systemAbilityJson, SA_TAG_RUN_ON_CREATE, saProfile.runOnCreate); 395 GetBoolFromJson(systemAbilityJson, SA_TAG_MODULE_UPDATE, saProfile.moduleUpdate); 396 GetBoolFromJson(systemAbilityJson, SA_TAG_AUTO_RESTART, saProfile.autoRestart); 397 GetBoolFromJson(systemAbilityJson, SA_TAG_DISTRIBUTED, saProfile.distributed); 398 GetBoolFromJson(systemAbilityJson, SA_TAG_CACHE_COMMON_EVENT, saProfile.cacheCommonEvent); 399 GetIntArrayFromJson(systemAbilityJson, SA_TAG_DEPEND, saProfile.dependSa); 400 GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT, saProfile.dependTimeout); 401 if (saProfile.dependTimeout == 0) { 402 GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY, saProfile.dependTimeout); 403 } 404 GetInt32FromJson(systemAbilityJson, SA_TAG_DUMP_LEVEL, saProfile.dumpLevel); 405 string capability; 406 GetStringFromJson(systemAbilityJson, SA_TAG_CAPABILITY, capability); 407 saProfile.capability = capability.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(capability) : u""; 408 string permission; 409 GetStringFromJson(systemAbilityJson, SA_TAG_PERMISSION, permission); 410 saProfile.permission = permission.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(permission) : u""; 411 string bootPhase; 412 GetStringFromJson(systemAbilityJson, SA_TAG_BOOT_PHASE, bootPhase); 413 saProfile.bootPhase = GetBootPriorityPara(bootPhase); 414 // parse start-on-demand tag 415 ParseStartOndemandTag(systemAbilityJson, SA_TAG_START_ON_DEMAND, saProfile.startOnDemand); 416 // parse stop-on-demand tag 417 ParseStopOndemandTag(systemAbilityJson, SA_TAG_STOP_ON_DEMAND, saProfile.stopOnDemand); 418 string recycleStrategy; 419 GetStringFromJson(systemAbilityJson, SA_TAG_RECYCLE_STRATEGY, recycleStrategy); 420 if (!CheckRecycleStrategy(recycleStrategy, saProfile.recycleStrategy)) { 421 HILOGE("profile format error: recycleStrategy: %{public}s is not immediately or low-memory", 422 recycleStrategy.c_str()); 423 return false; 424 } 425 if (!ParseSystemAbilityGetExtension(saProfile, systemAbilityJson)) { 426 return false; 427 } 428 return true; 429} 430 431bool ParseUtil::ParseSystemAbility(SaProfile& saProfile, nlohmann::json& systemAbilityJson) 432{ 433 HILOGD("ParseSystemAbility begin"); 434 if (!ParseSystemAbilityGetSaBaseInfo(saProfile, systemAbilityJson)) { 435 return false; 436 } 437 if (!ParseSystemAbilityGetSaExtInfo(saProfile, systemAbilityJson)) { 438 return false; 439 } 440 HILOGD("ParseSystemAbility end"); 441 return true; 442} 443 444bool ParseUtil::CheckRecycleStrategy(const std::string& recycleStrategyStr, int32_t& recycleStrategy) 445{ 446 if (recycleStrategyStr == "" || recycleStrategyStr == "immediately") { 447 recycleStrategy = IMMEDIATELY; 448 return true; 449 } else if (recycleStrategyStr == "low-memory") { 450 recycleStrategy = LOW_MEMORY; 451 return true; 452 } 453 return false; 454} 455 456bool ParseUtil::ParseJsonTag(const nlohmann::json& systemAbilityJson, const std::string& jsonTag, 457 nlohmann::json& onDemandJson) 458{ 459 if (systemAbilityJson.find(jsonTag) == systemAbilityJson.end()) { 460 return false; 461 } 462 onDemandJson = systemAbilityJson.at(jsonTag); 463 if (!onDemandJson.is_object()) { 464 HILOGE("parse ondemand tag error"); 465 return false; 466 } 467 return true; 468} 469 470void ParseUtil::ParseOndemandTag(const nlohmann::json& onDemandJson, std::vector<OnDemandEvent>& onDemandEvents) 471{ 472 GetOnDemandArrayFromJson(DEVICE_ONLINE, onDemandJson, SA_TAG_DEVICE_ON_LINE, onDemandEvents); 473 GetOnDemandArrayFromJson(SETTING_SWITCH, onDemandJson, SA_TAG_SETTING_SWITCH, onDemandEvents); 474 GetOnDemandArrayFromJson(COMMON_EVENT, onDemandJson, SA_TAG_COMMON_EVENT, onDemandEvents); 475 GetOnDemandArrayFromJson(PARAM, onDemandJson, SA_TAG_PARAM, onDemandEvents); 476 GetOnDemandArrayFromJson(TIMED_EVENT, onDemandJson, SA_TAG_TIEMD_EVENT, onDemandEvents); 477} 478 479void ParseUtil::ParseStartOndemandTag(const nlohmann::json& systemAbilityJson, 480 const std::string& jsonTag, StartOnDemand& startOnDemand) 481{ 482 nlohmann::json onDemandJson; 483 if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) { 484 return; 485 } 486 ParseOndemandTag(onDemandJson, startOnDemand.onDemandEvents); 487 GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, startOnDemand.allowUpdate); 488} 489 490void ParseUtil::ParseStopOndemandTag(const nlohmann::json& systemAbilityJson, 491 const std::string& jsonTag, StopOnDemand& stopOnDemand) 492{ 493 nlohmann::json onDemandJson; 494 if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) { 495 return; 496 } 497 ParseOndemandTag(onDemandJson, stopOnDemand.onDemandEvents); 498 GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, stopOnDemand.allowUpdate); 499 GetBoolFromJson(onDemandJson, SA_TAG_UNREF_UNLOAD, stopOnDemand.unrefUnload); 500 GetInt32FromJson(onDemandJson, SA_TAG_RECYCLE_DELAYTIME, stopOnDemand.delayTime); 501 GetInt32FromJson(onDemandJson, SA_TAG_LONGTIMEUNUSED_UNLOAD, stopOnDemand.unusedTimeout); 502} 503 504void ParseUtil::GetOnDemandArrayFromJson(int32_t eventId, const nlohmann::json& obj, 505 const std::string& key, std::vector<OnDemandEvent>& out) 506{ 507 if (obj.find(key.c_str()) != obj.end() && obj[key.c_str()].is_array()) { 508 for (auto& item : obj[key.c_str()]) { 509 std::string name; 510 GetStringFromJson(item, "name", name); 511 std::string value; 512 GetStringFromJson(item, "value", value); 513 bool persistence = false; 514 GetBoolFromJson(item, "persistence", persistence); 515 std::vector<OnDemandCondition> conditions; 516 GetOnDemandConditionsFromJson(item, "conditions", conditions); 517 HILOGD("conditions size: %{public}zu", conditions.size()); 518 bool enableOnce = false; 519 GetBoolFromJson(item, "enable-once", enableOnce); 520 std::string priority; 521 GetStringFromJson(item, "load-priority", priority); 522 uint32_t loadPriority = GetOndemandPriorityPara(priority); 523 std::map<std::string, std::string> extraMessages; 524 GetOnDemandExtraMessagesFromJson(item, "extra-messages", extraMessages); 525 HILOGD("extraMessages size: %{public}zu", extraMessages.size()); 526 if (!name.empty() && name.length() <= MAX_JSON_STRING_LENGTH && 527 value.length() <= MAX_JSON_STRING_LENGTH) { 528 OnDemandEvent event = {eventId, name, value, -1, persistence, 529 conditions, enableOnce, loadPriority, extraMessages}; 530 out.emplace_back(event); 531 } 532 } 533 } 534} 535 536void ParseUtil::GetOnDemandExtraMessagesFromJson(const nlohmann::json& obj, 537 const std::string& key, std::map<std::string, std::string>& out) 538{ 539 if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_object()) { 540 return; 541 } 542 for (auto &it: obj[key.c_str()].items()) { 543 if (it.value().is_string()) { 544 out[it.key()] = it.value(); 545 } else { 546 HILOGW("extra-mesasge: not string type"); 547 } 548 } 549} 550 551void ParseUtil::GetOnDemandConditionsFromJson(const nlohmann::json& obj, 552 const std::string& key, std::vector<OnDemandCondition>& out) 553{ 554 nlohmann::json conditionsJson; 555 if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_array()) { 556 return; 557 } 558 conditionsJson = obj.at(key.c_str()); 559 for (auto& condition : conditionsJson) { 560 std::string type; 561 GetStringFromJson(condition, "eventId", type); 562 std::string name; 563 GetStringFromJson(condition, "name", name); 564 std::string value; 565 GetStringFromJson(condition, "value", value); 566 int32_t eventId = 0; 567 if (type == SA_TAG_DEVICE_ON_LINE) { 568 eventId = DEVICE_ONLINE; 569 } else if (type == SA_TAG_SETTING_SWITCH) { 570 eventId = SETTING_SWITCH; 571 } else if (type == SA_TAG_COMMON_EVENT) { 572 eventId = COMMON_EVENT; 573 } else if (type == SA_TAG_PARAM) { 574 eventId = PARAM; 575 } else if (type == SA_TAG_TIEMD_EVENT) { 576 eventId = TIMED_EVENT; 577 } else { 578 HILOGW("invalid condition eventId: %{public}s", type.c_str()); 579 continue; 580 } 581 std::map<std::string, std::string> extraMessages; 582 GetOnDemandExtraMessagesFromJson(condition, "extra-messages", extraMessages); 583 OnDemandCondition conditionEvent = {eventId, name, value, extraMessages}; 584 out.emplace_back(conditionEvent); 585 } 586} 587 588std::u16string ParseUtil::GetProcessName() const 589{ 590 return procName_; 591} 592 593string ParseUtil::GetRealPath(const string& profilePath) const 594{ 595 char path[PATH_MAX] = {'\0'}; 596 if (realpath(profilePath.c_str(), path) == nullptr) { 597 HILOGD("get real path fail"); 598 return ""; 599 } 600 string realPath(path); 601 return realPath; 602} 603 604bool ParseUtil::CheckPathExist(const string& profilePath) 605{ 606 std::ifstream profileStream(profilePath.c_str()); 607 return profileStream.good(); 608} 609 610bool ParseUtil::ParseTrustConfig(const string& profilePath, 611 std::map<std::u16string, std::set<int32_t>>& values) 612{ 613 HILOGD("config path:%{private}s", profilePath.c_str()); 614 string realPath = GetRealPath(profilePath); 615 if (!CheckPathExist(realPath.c_str())) { 616 HILOGE("bad profile path!"); 617 return false; 618 } 619 nlohmann::json trustSaIdJson; 620 bool result = ParseJsonObj(trustSaIdJson, realPath); 621 if (!result) { 622 HILOGE("trust json file parse error!"); 623 return false; 624 } 625 string process; 626 GetStringFromJson(trustSaIdJson, SA_TAG_PROCESS, process); 627 if (process.empty()) { 628 HILOGE("trust profile format error: no process tag"); 629 return false; 630 } 631 if (process.length() > MAX_JSON_STRING_LENGTH) { 632 HILOGE("trust profile format error: process is too long"); 633 return false; 634 } 635 auto& saIds = values[Str8ToStr16(process)]; 636 GetIntArrayFromJson(trustSaIdJson, SA_TAG_SAID, saIds); 637 HILOGI("ParseTrustConfig realPath:%{public}s, saIds size = %{public}zu", realPath.c_str(), saIds.size()); 638 return true; 639} 640 641bool ParseUtil::ParseJsonObj(nlohmann::json& jsonObj, const string& jsonPath) 642{ 643 std::ifstream jsonFileStream; 644 jsonFileStream.open(jsonPath.c_str(), std::ios::in); 645 if (!jsonFileStream.is_open()) { 646 HILOGE("open json file error!!"); 647 return false; 648 } 649 std::ostringstream buffer; 650 char ch; 651 int32_t readSize = 0; 652 while (buffer && jsonFileStream.get(ch)) { 653 readSize++; 654 if (readSize < MAX_JSON_OBJECT_SIZE) { 655 buffer.put(ch); 656 } else { 657 jsonFileStream.close(); 658 HILOGE("too big json file error!!"); 659 return false; 660 } 661 } 662 jsonFileStream.close(); 663 string jsonStr = buffer.str(); 664 jsonObj = nlohmann::json::parse(jsonStr, nullptr, false); 665 if (jsonObj.is_discarded()) { 666 HILOGE("parse json obj error!!"); 667 return false; 668 } 669 return true; 670} 671 672bool ParseUtil::CheckLogicRelationship(const std::string& state, const std::string& profile) 673{ 674 HILOGD("CheckLogicRelationship State:%{public}s || Profile:%{public}s", state.c_str(), profile.c_str()); 675 if (profile.empty() || state == profile) { 676 return true; 677 } 678 if (state.empty()) { 679 return false; 680 } 681 int32_t logicRelationship = EQ; 682 int32_t valueStartPosition = 0; 683 if (profile[0] == '>') { 684 valueStartPosition ++; 685 if (profile[1] == '=') { 686 valueStartPosition ++; 687 logicRelationship = GREATER_EQ; 688 } else { 689 logicRelationship = GREATER; 690 } 691 } else if (profile[0] == '<') { 692 valueStartPosition ++; 693 if (profile[1] == '=') { 694 valueStartPosition ++; 695 logicRelationship = LESS_EQ; 696 } else { 697 logicRelationship = LESS; 698 } 699 } 700 int32_t stateInt, profileInt; 701 if (!StrToInt(profile.substr(valueStartPosition, profile.length() - 1), profileInt)) { 702 return false; 703 } 704 if (!StrToInt(state, stateInt)) { 705 return false; 706 } 707 if (logicRelationship == EQ) { 708 return stateInt == profileInt; 709 } else if (logicRelationship == GREATER_EQ) { 710 return stateInt >= profileInt; 711 } else if (logicRelationship == GREATER) { 712 return stateInt > profileInt; 713 } else if (logicRelationship == LESS_EQ) { 714 return stateInt <= profileInt; 715 } else if (logicRelationship == LESS) { 716 return stateInt < profileInt; 717 } 718 return false; 719} 720} // namespace OHOS 721