1 /*
2  * Copyright (c) 2024 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 #include "area_policy.h"
16 
17 #include <unordered_map>
18 
19 #include "hiview_logger.h"
20 #include "parameter_ex.h"
21 #include "string_util.h"
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 DEFINE_LOG_TAG("AreaPolicy");
26 namespace {
27 const std::unordered_map<std::string, uint8_t> EVENT_LEVELS = {
28     {"DEBUG", 1}, {"INFO", 2}, {"MINOR", 3}, {"MAJOR", 4}, {"CRITICAL", 5}
29 };
30 }
31 
AreaPolicy(const std::string & configPath)32 AreaPolicy::AreaPolicy(const std::string& configPath)
33 {
34     Parse(configPath);
35 }
36 
Parse(const std::string & configPath)37 void AreaPolicy::Parse(const std::string& configPath)
38 {
39     auto root = CJsonUtil::ParseJsonRoot(configPath);
40     if (root == nullptr) {
41         HIVIEW_LOGW("failed to parse config file=%{public}s", configPath.c_str());
42         return;
43     }
44     std::string version = Parameter::GetVersionStr();
45     auto config = CJsonUtil::GetArrayValue(root, version);
46     if (config == nullptr) {
47         HIVIEW_LOGW("failed to parse config file=%{public}s, version=%{public}s",
48             configPath.c_str(), version.c_str());
49         cJSON_Delete(root);
50         return;
51     }
52     if (!ParseAllowedInfos(config)) {
53         HIVIEW_LOGW("failed to parse allowed info, file=%{public}s, version=%{public}s",
54             configPath.c_str(), version.c_str());
55     }
56     cJSON_Delete(root);
57 }
58 
ParseAllowedInfos(const cJSON * config)59 bool AreaPolicy::ParseAllowedInfos(const cJSON* config)
60 {
61     cJSON* areaConfig = nullptr;
62     int32_t regionCode = Parameter::GetRegionCode();
63     cJSON_ArrayForEach(areaConfig, config) {
64         if (!cJSON_IsObject(areaConfig)) {
65             HIVIEW_LOGW("area config is not object");
66             return false;
67         }
68 
69         if (ParseAllowedInfo(areaConfig, regionCode)) {
70             HIVIEW_LOGI("succ to parse, code=%{public}d, allowLevel=%{public}d, allowPrivacy=%{public}d, "
71                 "allowSysUe=%{public}d, allowUe=%{public}d", regionCode, allowedInfo_.allowLevel,
72                 allowedInfo_.allowPrivacy, allowedInfo_.allowSysUe, allowedInfo_.allowUe);
73             return true;
74         }
75     }
76     return false;
77 }
78 
ParseAllowedInfo(const cJSON * config,int32_t regionCode)79 bool AreaPolicy::ParseAllowedInfo(const cJSON* config, int32_t regionCode)
80 {
81     int32_t codeValue = CJsonUtil::GetIntValue(config, "code");
82     if (codeValue != regionCode) {
83         return false;
84     }
85 
86     const std::string allowLevelKey = "allowLevel";
87     int32_t allowLevelValue = CJsonUtil::GetIntValue(config, allowLevelKey);
88     if (allowLevelValue <= 0) {
89         HIVIEW_LOGW("failed to parse key=%{public}s, value=%{public}d",
90             allowLevelKey.c_str(), allowLevelValue);
91         return false;
92     }
93 
94     const std::string allowPrivacyKey = "allowPrivacy";
95     int32_t allowPrivacyValue = CJsonUtil::GetIntValue(config, allowPrivacyKey);
96     if (allowPrivacyValue <= 0) {
97         HIVIEW_LOGW("failed to parse key=%{public}s, value=%{public}d",
98             allowPrivacyKey.c_str(), allowPrivacyValue);
99         return false;
100     }
101 
102     const std::string allowSysUeKey = "allowSysUe";
103     bool allowSysUeValue = true;
104     if (!CJsonUtil::GetBoolValue(config, allowSysUeKey, allowSysUeValue)) {
105         HIVIEW_LOGW("failed to parse key=%{public}s, value=%{public}d",
106             allowSysUeKey.c_str(), allowSysUeValue);
107         return false;
108     }
109 
110     const std::string allowUeKey = "allowUe";
111     bool allowUeValue = true;
112     if (!CJsonUtil::GetBoolValue(config, allowUeKey, allowUeValue)) {
113         HIVIEW_LOGW("failed to parse key=%{public}s, value=%{public}d",
114             allowUeKey.c_str(), allowUeValue);
115         return false;
116     }
117 
118     allowedInfo_.allowLevel = static_cast<uint8_t>(allowLevelValue);
119     allowedInfo_.allowPrivacy = static_cast<uint8_t>(allowPrivacyValue);
120     allowedInfo_.allowSysUe = allowSysUeValue;
121     allowedInfo_.allowUe = allowUeValue;
122     return true;
123 }
124 
IsAllowed(std::shared_ptr<SysEvent> event) const125 bool AreaPolicy::IsAllowed(std::shared_ptr<SysEvent> event) const
126 {
127     return IsAllowedLevel(event) && IsAllowedPrivacy(event) && IsAllowedUe(event);
128 }
129 
IsAllowedLevel(std::shared_ptr<SysEvent> event) const130 bool AreaPolicy::IsAllowedLevel(std::shared_ptr<SysEvent> event) const
131 {
132     std::string levelStr = event->GetLevel();
133     if (EVENT_LEVELS.find(levelStr) == EVENT_LEVELS.end()) {
134         HIVIEW_LOGD("event level=%{public}s is invalid", levelStr.c_str());
135         return false;
136     }
137     uint8_t level = EVENT_LEVELS.at(levelStr);
138     return level >= allowedInfo_.allowLevel;
139 }
140 
IsAllowedPrivacy(std::shared_ptr<SysEvent> event) const141 bool AreaPolicy::IsAllowedPrivacy(std::shared_ptr<SysEvent> event) const
142 {
143     return event->GetPrivacy() >= allowedInfo_.allowPrivacy;
144 }
145 
IsAllowedUe(std::shared_ptr<SysEvent> event) const146 bool AreaPolicy::IsAllowedUe(std::shared_ptr<SysEvent> event) const
147 {
148     if (StringUtil::EndWith(event->domain_, "_UE")) {
149         return allowedInfo_.allowUe;
150     } else if (event->eventType_ == 4) { // 4: behavior event
151         return allowedInfo_.allowSysUe;
152     } else {
153         return true;
154     }
155 }
156 } // namespace HiviewDFX
157 } // namespace OHOS
158