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