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 "thermal_hdf_config.h" 17 18#include "thermal_hdf_utils.h" 19#include "thermal_log.h" 20#include "hdf_remote_service.h" 21#include "osal_mem.h" 22#include "string_ex.h" 23 24namespace OHOS { 25namespace HDI { 26namespace Thermal { 27namespace V1_1 { 28namespace { 29const int32_t DEFAULT_POLLING_INTERVAL = 30000; 30} 31 32ThermalHdfConfig& ThermalHdfConfig::GetInstance() 33{ 34 static ThermalHdfConfig instance; 35 return instance; 36} 37 38int32_t ThermalHdfConfig::ThermalHDIConfigInit(const std::string& path) 39{ 40 if (!baseConfig_) { 41 baseConfig_ = std::make_shared<BaseInfoConfig>(); 42 } 43 return ParseThermalHdiXMLConfig(path); 44} 45 46int32_t ThermalHdfConfig::ParseThermalHdiXMLConfig(const std::string& path) 47{ 48 std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr( 49 xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc); 50 if (docPtr == nullptr) { 51 THERMAL_HILOGW(COMP_HDI, "failed to read xml file"); 52 return HDF_ERR_INVALID_OBJECT; 53 } 54 55 auto rootNode = xmlDocGetRootElement(docPtr.get()); 56 if (rootNode == nullptr) { 57 THERMAL_HILOGE(COMP_HDI, "failed to read root node"); 58 return HDF_ERR_INVALID_OBJECT; 59 } 60 61 if (!xmlStrcmp(rootNode->name, BAD_CAST"thermal")) { 62 xmlChar* xmlVersion = xmlGetProp(rootNode, BAD_CAST"version"); 63 if (xmlVersion != nullptr) { 64 this->thermal_.version = std::string(reinterpret_cast<char*>(xmlVersion)); 65 xmlFree(xmlVersion); 66 THERMAL_HILOGD(COMP_HDI, "version: %{public}s", this->thermal_.version.c_str()); 67 } 68 69 xmlChar* xmlProduct = xmlGetProp(rootNode, BAD_CAST"product"); 70 if (xmlProduct != nullptr) { 71 this->thermal_.product = std::string(reinterpret_cast<char*>(xmlProduct)); 72 xmlFree(xmlProduct); 73 THERMAL_HILOGD(COMP_HDI, "product: %{public}s", this->thermal_.product.c_str()); 74 } 75 } 76 77 for (auto node = rootNode->children; node; node = node->next) { 78 if (node == nullptr) { 79 continue; 80 } 81 82 if (!xmlStrcmp(node->name, BAD_CAST"base")) { 83 ParseBaseNode(node); 84 } else if (!xmlStrcmp(node->name, BAD_CAST"polling")) { 85 ParsePollingNode(node); 86 } else if (!xmlStrcmp(node->name, BAD_CAST"tracing")) { 87 ParseTracingNode(node); 88 } else if (!xmlStrcmp(node->name, BAD_CAST"isolate")) { 89 ParseIsolateNode(node); 90 } 91 } 92 return HDF_SUCCESS; 93} 94 95void ThermalHdfConfig::ParseBaseNode(xmlNodePtr node) 96{ 97 auto cur = node->xmlChildrenNode; 98 std::vector<BaseItem> vBase; 99 while (cur != nullptr) { 100 BaseItem item; 101 xmlChar* xmlTag = xmlGetProp(cur, BAD_CAST"tag"); 102 if (xmlTag != nullptr) { 103 item.tag = std::string(reinterpret_cast<char*>(xmlTag)); 104 xmlFree(xmlTag); 105 THERMAL_HILOGD(COMP_HDI, "ParseBaseNode tag: %{public}s", item.tag.c_str()); 106 } 107 108 xmlChar* xmlValue = xmlGetProp(cur, BAD_CAST"value"); 109 if (xmlValue != nullptr) { 110 item.value = std::string(reinterpret_cast<char*>(xmlValue)); 111 xmlFree(xmlValue); 112 THERMAL_HILOGD(COMP_HDI, "ParseBaseNode value: %{public}s", item.value.c_str()); 113 } 114 115 vBase.push_back(item); 116 cur = cur->next; 117 } 118 baseConfig_->SetBase(vBase); 119} 120 121std::string ThermalHdfConfig::GetXmlNodeName(xmlNodePtr node, std::string &defaultName) 122{ 123 std::string name; 124 xmlChar* xmlName = xmlGetProp(node, BAD_CAST"name"); 125 if (xmlName == nullptr) { 126 return defaultName; 127 } 128 name = std::string(reinterpret_cast<char*>(xmlName)); 129 xmlFree(xmlName); 130 131 return name; 132} 133 134void ThermalHdfConfig::ParsePollingNode(xmlNodePtr node) 135{ 136 std::string pollingDefaultName("thermal"); 137 std::string pollingName = GetXmlNodeName(node, pollingDefaultName); 138 GroupMap groupMap; 139 140 auto cur = node->xmlChildrenNode; 141 while (cur != nullptr) { 142 std::shared_ptr<SensorInfoConfig> sensorInfo = std::make_shared<SensorInfoConfig>(); 143 std::string groupDefaultName("actual"); 144 std::string groupName = GetXmlNodeName(cur, groupDefaultName); 145 sensorInfo->SetGroupName(groupName); 146 THERMAL_HILOGD(COMP_HDI, "ParsePollingNode groupName: %{public}s", groupName.c_str()); 147 148 xmlChar* xmlInterval = xmlGetProp(cur, BAD_CAST"interval"); 149 if (xmlInterval != nullptr) { 150 std::string strInterval = reinterpret_cast<char *>(xmlInterval); 151 int32_t interval = DEFAULT_POLLING_INTERVAL; 152 StrToInt(TrimStr(strInterval), interval); 153 xmlFree(xmlInterval); 154 THERMAL_HILOGD(COMP_HDI, "ParsePollingNode interval: %{public}d", interval); 155 sensorInfo->SetGroupInterval(interval); 156 } 157 158 std::vector<XMLThermalZoneInfo> xmlTzInfoList; 159 std::vector<XMLThermalNodeInfo> xmlTnInfoList; 160 for (auto subNode = cur->children; subNode; subNode = subNode->next) { 161 if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_zone")) { 162 XMLThermalZoneInfo tz; 163 GetThermalZoneNodeInfo(tz, subNode); 164 THERMAL_HILOGI(COMP_HDI, "ParsePollingNode ParsePollingNodetztype: %{public}s, replace: %{public}s", 165 tz.type.c_str(), tz.replace.c_str()); 166 xmlTzInfoList.push_back(tz); 167 } else if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) { 168 XMLThermalNodeInfo tn; 169 ParsePollingSubNode(subNode, tn); 170 THERMAL_HILOGI(COMP_HDI, "ParsePollingNode tntype: %{public}s", tn.type.c_str()); 171 xmlTnInfoList.push_back(tn); 172 } 173 } 174 sensorInfo->SetXMLThermalZoneInfo(xmlTzInfoList); 175 sensorInfo->SetXMLThermalNodeInfo(xmlTnInfoList); 176 groupMap.insert(std::make_pair(groupName, sensorInfo)); 177 cur = cur->next; 178 } 179 180 pollingMap_.insert(std::make_pair(pollingName, groupMap)); 181} 182 183void ThermalHdfConfig::ParsePollingSubNode(xmlNodePtr node, XMLThermalNodeInfo& tn) 184{ 185 DfxTraceInfo info; 186 187 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type"); 188 if (xmlType != nullptr) { 189 tn.type = std::string(reinterpret_cast<char*>(xmlType)); 190 xmlFree(xmlType); 191 } 192 193 xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path"); 194 if (xmlPath != nullptr) { 195 tn.path = std::string(reinterpret_cast<char*>(xmlPath)); 196 xmlFree(xmlPath); 197 } 198} 199 200void ThermalHdfConfig::ParseTracingNode(xmlNodePtr node) 201{ 202 xmlChar* xmlOutpath = xmlGetProp(node, BAD_CAST"outpath"); 203 if (xmlOutpath != nullptr) { 204 if (strcmp(reinterpret_cast<char *>(xmlOutpath), "/data/log/thermal/thermal-log") == 0) { 205 this->traceConfig_.outPath = std::string(reinterpret_cast<char *>(xmlOutpath)); 206 xmlFree(xmlOutpath); 207 } else { 208 THERMAL_HILOGE(COMP_HDI, "xmlOutpath is not /data/log/thermal/thermal-log"); 209 } 210 } 211 212 auto cur = node->xmlChildrenNode; 213 while (cur != nullptr) { 214 ParseTracingSubNode(cur); 215 cur = cur->next; 216 } 217 218 THERMAL_HILOGI(COMP_HDI, "DfxTraceInfo number = %{public}zu", traceInfo_.size()); 219} 220 221void ThermalHdfConfig::ParseTracingSubNode(xmlNodePtr node) 222{ 223 DfxTraceInfo info; 224 std::string title; 225 std::string valuePath; 226 227 for (auto subNode = node->children; subNode != nullptr; subNode = subNode->next) { 228 if (!xmlStrcmp(subNode->name, BAD_CAST"title")) { 229 xmlChar* titlePath = xmlGetProp(subNode, BAD_CAST"path"); 230 if (titlePath != nullptr) { 231 ThermalHdfUtils::ReadNode(std::string(reinterpret_cast<char*>(titlePath)), title); 232 xmlFree(titlePath); 233 } 234 235 xmlChar* titleName = xmlGetProp(subNode, BAD_CAST"name"); 236 if (titleName != nullptr) { 237 title = std::string(reinterpret_cast<char*>(titleName)); 238 xmlFree(titleName); 239 } 240 } 241 242 if (!xmlStrcmp(subNode->name, BAD_CAST"value")) { 243 xmlChar* xmlValuePath = xmlGetProp(subNode, BAD_CAST"path"); 244 if (xmlValuePath != nullptr) { 245 valuePath = std::string(reinterpret_cast<char*>(xmlValuePath)); 246 xmlFree(xmlValuePath); 247 } 248 } 249 } 250 251 info.title = title; 252 info.valuePath = valuePath; 253 traceInfo_.emplace_back(info); 254 THERMAL_HILOGD( 255 COMP_HDI, "traceInfo.title = %{public}s, traceInfo.valuePath = %{private}s", title.c_str(), valuePath.c_str()); 256} 257 258void ThermalHdfConfig::GetThermalZoneNodeInfo(XMLThermalZoneInfo& tz, const xmlNode* node) 259{ 260 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type"); 261 if (xmlType != nullptr) { 262 tz.type = std::string(reinterpret_cast<char*>(xmlType)); 263 xmlFree(xmlType); 264 } 265 266 auto replace = xmlGetProp(node, BAD_CAST("replace")); 267 if (replace != nullptr) { 268 tz.replace = std::string(reinterpret_cast<char*>(replace)); 269 tz.isReplace = true; 270 xmlFree(replace); 271 } 272} 273 274void ThermalHdfConfig::ParseIsolateNode(xmlNodePtr node) 275{ 276 THERMAL_HILOGD(COMP_HDI, "in"); 277 auto cur = node->xmlChildrenNode; 278 while (cur != nullptr) { 279 std::shared_ptr<IsolateInfoConfig> isolateInfo = std::make_shared<IsolateInfoConfig>(); 280 std::string groupName; 281 xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name"); 282 if (xmlName != nullptr) { 283 groupName = std::string(reinterpret_cast<char*>(xmlName)); 284 xmlFree(xmlName); 285 isolateInfo->SetGroupName(groupName); 286 THERMAL_HILOGD(COMP_HDI, "groupName: %{public}s", groupName.c_str()); 287 } 288 289 std::vector<IsolateNodeInfo> xmlTnInfoList; 290 for (auto subNode = cur->children; subNode; subNode = subNode->next) { 291 if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) { 292 IsolateNodeInfo tn; 293 ParseIsolateSubNode(subNode, tn); 294 xmlTnInfoList.push_back(tn); 295 } 296 } 297 isolateInfo->SetIsolateNodeInfo(xmlTnInfoList); 298 isolateInfoMap_.insert(std::make_pair(groupName, isolateInfo)); 299 cur = cur->next; 300 } 301} 302 303void ThermalHdfConfig::ParseIsolateSubNode(xmlNodePtr node, IsolateNodeInfo& tn) 304{ 305 xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type"); 306 if (xmlType != nullptr) { 307 tn.type = std::string(reinterpret_cast<char*>(xmlType)); 308 THERMAL_HILOGD(COMP_HDI, "type: %{public}s", tn.type.c_str()); 309 xmlFree(xmlType); 310 } 311 312 xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path"); 313 if (xmlPath != nullptr) { 314 tn.path = std::string(reinterpret_cast<char*>(xmlPath)); 315 THERMAL_HILOGD(COMP_HDI, "path: %{public}s", tn.path.c_str()); 316 xmlFree(xmlPath); 317 } 318} 319 320int32_t ThermalHdfConfig::GetIsolateCpuNodePath(bool isSim, const std::string &type, std::string &path) 321{ 322 std::string groupName = isSim ? "sim" : "actual"; 323 THERMAL_HILOGI(COMP_HDI, "isSim %d, type %{public}s, groupName %{public}s", isSim, type.c_str(), groupName.c_str()); 324 325 auto mapIter = isolateInfoMap_.find(groupName); 326 if (mapIter == isolateInfoMap_.end()) { 327 THERMAL_HILOGE(COMP_HDI, "failed to get group %s config", groupName.c_str()); 328 return HDF_FAILURE; 329 } 330 331 std::vector<IsolateNodeInfo> nodeVector = mapIter->second->GetIsolateNodeInfo(); 332 for (auto nodeIter : nodeVector) { 333 if (type == nodeIter.type) { 334 path = nodeIter.path; 335 THERMAL_HILOGI(COMP_HDI, "path %{public}s", path.c_str()); 336 return HDF_SUCCESS; 337 } 338 } 339 340 THERMAL_HILOGE(COMP_HDI, "failed to get type %{public}s path", type.c_str()); 341 return HDF_FAILURE; 342} 343} // V1_1 344} // Thermal 345} // HDI 346} // OHOS 347