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