• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "event_json_parser.h"
17 
18 #include <cctype>
19 #include <cinttypes>
20 #include <fstream>
21 #include <map>
22 
23 #include "hiview_config_util.h"
24 #include "hiview_logger.h"
25 #include "parameter_ex.h"
26 #include "privacy_manager.h"
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 DEFINE_LOG_TAG("Event-JsonParser");
32 
33 constexpr char BASE[] = "__BASE";
34 constexpr char LEVEL[] = "level";
35 constexpr char TAG[] = "tag";
36 constexpr char TYPE[] = "type";
37 constexpr char PRIVACY[] = "privacy";
38 constexpr char PRESERVE[] = "preserve";
39 constexpr char COLLECT[] = "collect";
40 constexpr char REPORT_INTERVAL[] = "reportInterval";
41 const std::map<std::string, uint8_t> EVENT_TYPE_MAP = {
42     {"FAULT", 1}, {"STATISTIC", 2}, {"SECURITY", 3}, {"BEHAVIOR", 4}
43 };
44 
ReadSysEventDefFromFile(const std::string & path,Json::Value & hiSysEventDef)45 bool ReadSysEventDefFromFile(const std::string& path, Json::Value& hiSysEventDef)
46 {
47     std::ifstream fin(path, std::ifstream::binary);
48     if (!fin.is_open()) {
49         HIVIEW_LOGW("failed to open file, path: %{public}s.", path.c_str());
50         return false;
51     }
52     Json::CharReaderBuilder jsonRBuilder;
53     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
54     JSONCPP_STRING errs;
55     return parseFromStream(jsonRBuilder, fin, &hiSysEventDef, &errs);
56 }
57 
AddEventToExportList(ExportEventList & list,const std::string & domain,const std::string & name,const BaseInfo & baseInfo)58 void AddEventToExportList(ExportEventList& list, const std::string& domain, const std::string& name,
59     const BaseInfo& baseInfo)
60 {
61     if (baseInfo.keyConfig.preserve != DEFAULT_PERSERVE_VAL || baseInfo.keyConfig.collect == DEFAULT_COLLECT_VAL) {
62         return;
63     }
64     auto foundRet = list.find(domain);
65     if (foundRet == list.end()) {
66         list.emplace(domain, std::vector<std::string> { name });
67         return;
68     }
69     foundRet->second.emplace_back(name);
70 }
71 }
72 
EventJsonParser()73 EventJsonParser::EventJsonParser()
74 {
75 }
76 
~EventJsonParser()77 EventJsonParser::~EventJsonParser()
78 {
79 }
80 
GetTagByDomainAndName(const std::string & domain,const std::string & name)81 std::string EventJsonParser::GetTagByDomainAndName(const std::string& domain, const std::string& name)
82 {
83     return GetDefinedBaseInfoByDomainName(domain, name).tag;
84 }
85 
GetTypeByDomainAndName(const std::string & domain,const std::string & name)86 uint8_t EventJsonParser::GetTypeByDomainAndName(const std::string& domain, const std::string& name)
87 {
88     return GetDefinedBaseInfoByDomainName(domain, name).keyConfig.type;
89 }
90 
GetPreserveByDomainAndName(const std::string & domain,const std::string & name)91 bool EventJsonParser::GetPreserveByDomainAndName(const std::string& domain, const std::string& name)
92 {
93     return GetDefinedBaseInfoByDomainName(domain, name).keyConfig.preserve;
94 }
95 
GetDefinedBaseInfoByDomainName(const std::string & domain,const std::string & name)96 BaseInfo EventJsonParser::GetDefinedBaseInfoByDomainName(const std::string& domain, const std::string& name)
97 {
98     std::unique_lock<ffrt::mutex> uniqueLock(defMtx_);
99     if (sysEventDefMap_ == nullptr) {
100         HIVIEW_LOGD("sys def map is null");
101         return BaseInfo();
102     }
103     auto domainIter = sysEventDefMap_->find(domain);
104     if (domainIter == sysEventDefMap_->end()) {
105         HIVIEW_LOGD("domain %{public}s is not defined.", domain.c_str());
106         return BaseInfo();
107     }
108     auto domainNames = sysEventDefMap_->at(domain);
109     auto nameIter = domainNames.find(name);
110     if (nameIter == domainNames.end()) {
111         HIVIEW_LOGD("%{public}s is not defined in domain %{public}s, or privacy not allowed.",
112             name.c_str(), domain.c_str());
113         return BaseInfo();
114     }
115     return nameIter->second;
116 }
117 
HasIntMember(const Json::Value & jsonObj,const std::string & name) const118 bool EventJsonParser::HasIntMember(const Json::Value& jsonObj, const std::string& name) const
119 {
120     return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isInt();
121 }
122 
HasUIntMember(const Json::Value & jsonObj,const std::string & name) const123 bool EventJsonParser::HasUIntMember(const Json::Value& jsonObj, const std::string& name) const
124 {
125     return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isUInt();
126 }
127 
HasStringMember(const Json::Value & jsonObj,const std::string & name) const128 bool EventJsonParser::HasStringMember(const Json::Value& jsonObj, const std::string& name) const
129 {
130     return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isString();
131 }
132 
HasBoolMember(const Json::Value & jsonObj,const std::string & name) const133 bool EventJsonParser::HasBoolMember(const Json::Value& jsonObj, const std::string& name) const
134 {
135     return jsonObj.isMember(name.c_str()) && jsonObj[name.c_str()].isBool();
136 }
137 
InitEventInfoMapRef(const Json::Value & eventJson,JSON_VALUE_LOOP_HANDLER handler) const138 void EventJsonParser::InitEventInfoMapRef(const Json::Value& eventJson, JSON_VALUE_LOOP_HANDLER handler) const
139 {
140     if (!eventJson.isObject()) {
141         return;
142     }
143     auto attrList = eventJson.getMemberNames();
144     for (auto it = attrList.cbegin(); it != attrList.cend(); it++) {
145         std::string key = *it;
146         if (key.empty()) {
147             continue;
148         }
149         if (handler != nullptr) {
150             handler(key, eventJson[key]);
151         }
152     }
153 }
154 
ParseBaseConfig(const Json::Value & eventNameJson) const155 BaseInfo EventJsonParser::ParseBaseConfig(const Json::Value& eventNameJson) const
156 {
157     BaseInfo baseInfo;
158     if (!eventNameJson.isObject() || !eventNameJson[BASE].isObject()) {
159         HIVIEW_LOGD("__BASE definition is invalid.");
160         return baseInfo;
161     }
162 
163     Json::Value baseJsonInfo = eventNameJson[BASE];
164     if (!baseJsonInfo.isObject() || !HasStringMember(baseJsonInfo, TYPE)) {
165         HIVIEW_LOGD("type is not defined in __BASE.");
166         return baseInfo;
167     }
168     std::string typeDes = baseJsonInfo[TYPE].asString();
169     if (EVENT_TYPE_MAP.find(typeDes) == EVENT_TYPE_MAP.end()) {
170         HIVIEW_LOGD("type is defined as %{public}s, but a valid type must be FAULT, STATISTIC, SECURITY, or BEHAVIOR",
171             typeDes.c_str());
172         return baseInfo;
173     }
174     baseInfo.keyConfig.type = EVENT_TYPE_MAP.at(typeDes);
175 
176     if (!HasStringMember(baseJsonInfo, LEVEL)) {
177         HIVIEW_LOGD("level is not defined in __BASE.");
178         return baseInfo;
179     }
180     baseInfo.level = baseJsonInfo[LEVEL].asString();
181 
182     if (HasStringMember(baseJsonInfo, TAG)) {
183         baseInfo.tag = baseJsonInfo[TAG].asString();
184     }
185     if (HasIntMember(baseJsonInfo, REPORT_INTERVAL)) {
186         baseInfo.reportInterval = static_cast<int16_t>(baseJsonInfo[REPORT_INTERVAL].asInt());
187     }
188 
189     if (HasUIntMember(baseJsonInfo, PRIVACY)) {
190         baseInfo.keyConfig.privacy = static_cast<uint8_t>(baseJsonInfo[PRIVACY].asUInt());
191     }
192 
193     if (HasBoolMember(baseJsonInfo, PRESERVE)) {
194         baseInfo.keyConfig.preserve = baseJsonInfo[PRESERVE].asBool() ? 1 : 0;
195     }
196 
197     if (HasBoolMember(baseJsonInfo, COLLECT)) {
198         baseInfo.keyConfig.collect = baseJsonInfo[COLLECT].asBool() ? 1 : 0;
199     }
200 
201     return baseInfo;
202 }
203 
ParseSysEventDef(const Json::Value & hiSysEventDef,std::shared_ptr<DOMAIN_INFO_MAP> sysDefMap)204 void EventJsonParser::ParseSysEventDef(const Json::Value& hiSysEventDef, std::shared_ptr<DOMAIN_INFO_MAP> sysDefMap)
205 {
206     InitEventInfoMapRef(hiSysEventDef, [this, sysDefMap] (const std::string& domain, const Json::Value& value) {
207        sysDefMap->insert(std::make_pair(domain, this->ParseEventNameConfig(domain, value)));
208     });
209 }
210 
ParseEventNameConfig(const std::string & domain,const Json::Value & domainJson) const211 NAME_INFO_MAP EventJsonParser::ParseEventNameConfig(const std::string& domain, const Json::Value& domainJson) const
212 {
213     NAME_INFO_MAP allNames;
214     InitEventInfoMapRef(domainJson,
215         [this, &domain, &allNames] (const std::string& eventName, const Json::Value& eventContent) {
216         BaseInfo baseInfo = ParseBaseConfig(eventContent);
217         if (PrivacyManager::IsAllowed(domain, baseInfo.keyConfig.type, baseInfo.level, baseInfo.keyConfig.privacy)) {
218             baseInfo.disallowParams = ParseEventParamInfo(eventContent);
219             allNames[eventName] = baseInfo;
220         } else {
221             HIVIEW_LOGD("not allowed event: %{public}s | %{public}s", domain.c_str(), eventName.c_str());
222         }
223     });
224     return allNames;
225 }
226 
ParseEventParamInfo(const Json::Value & eventContent) const227 PARAM_INFO_MAP_PTR EventJsonParser::ParseEventParamInfo(const Json::Value& eventContent) const
228 {
229     PARAM_INFO_MAP_PTR paramMaps = nullptr;
230     auto attrList = eventContent.getMemberNames();
231     if (attrList.empty()) {
232         return paramMaps;
233     }
234     for (const auto& paramName : attrList) {
235         if (paramName.empty() || paramName == BASE) {
236             // skip the definition of event, only care about the params
237             continue;
238         }
239         Json::Value paramContent = eventContent[paramName];
240         if (!paramContent.isObject()) {
241             continue;
242         }
243         if (!HasUIntMember(paramContent, PRIVACY)) {
244             // no privacy configured for this param, follow the event
245             continue;
246         }
247         uint8_t privacy = static_cast<uint8_t>(paramContent[PRIVACY].asUInt());
248         if (PrivacyManager::IsPrivacyAllowed(privacy)) {
249             // the privacy level of param is ok, no need to be recorded
250             continue;
251         }
252         if (paramMaps == nullptr) {
253             // if all params meet the privacy, no need to create the param instance
254             paramMaps = std::make_shared<std::map<std::string, std::shared_ptr<EventParamInfo>>>();
255         }
256         std::shared_ptr<EventParamInfo> paramInfo = nullptr;
257         if (Parameter::IsOversea() &&
258             HasStringMember(paramContent, "allowlist") && HasUIntMember(paramContent, "throwtype")) {
259             std::string allowListFile = paramContent["allowlist"].asString();
260             uint8_t throwType = static_cast<uint8_t>(paramContent["throwtype"].asUInt());
261             paramInfo = std::make_shared<EventParamInfo>(allowListFile, throwType);
262         }
263         paramMaps->insert(std::make_pair(paramName, paramInfo));
264     }
265     return paramMaps;
266 }
267 
ReadDefFile()268 void EventJsonParser::ReadDefFile()
269 {
270     auto defFilePath = HiViewConfigUtil::GetConfigFilePath("hisysevent.zip", "sys_event_def", "hisysevent.def");
271     HIVIEW_LOGI("read event def file path: %{public}s", defFilePath.c_str());
272     Json::Value hiSysEventDef;
273     if (!ReadSysEventDefFromFile(defFilePath, hiSysEventDef)) {
274         HIVIEW_LOGE("parse json file failed, please check the style of json file: %{public}s", defFilePath.c_str());
275         return;
276     }
277 
278     std::unique_lock<ffrt::mutex> uniqueLock(defMtx_);
279     if (sysEventDefMap_ == nullptr) {
280         sysEventDefMap_ = std::make_shared<DOMAIN_INFO_MAP>();
281     } else {
282         sysEventDefMap_->clear();
283     }
284     ParseSysEventDef(hiSysEventDef, sysEventDefMap_);
285 }
286 
OnConfigUpdate()287 void EventJsonParser::OnConfigUpdate()
288 {
289     // update privacy at first, because event define file depends on privacy config
290     PrivacyManager::OnConfigUpdate();
291     ReadDefFile();
292 }
293 
GetAllCollectEvents(ExportEventList & list)294 void EventJsonParser::GetAllCollectEvents(ExportEventList& list)
295 {
296     std::unique_lock<ffrt::mutex> uniqueLock(defMtx_);
297     if (sysEventDefMap_ == nullptr) {
298         return;
299     }
300     for (auto iter = sysEventDefMap_->cbegin(); iter != sysEventDefMap_->cend(); ++iter) {
301         for (const auto& eventDef : iter->second) {
302             AddEventToExportList(list, iter->first, eventDef.first, eventDef.second);
303         }
304     }
305 }
306 } // namespace HiviewDFX
307 } // namespace OHOS
308