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