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