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