/* * Copyright (c) 2022-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "thermal_hdf_config.h" #include "thermal_hdf_utils.h" #include "thermal_log.h" #include "hdf_remote_service.h" #include "osal_mem.h" #include "string_ex.h" namespace OHOS { namespace HDI { namespace Thermal { namespace V1_1 { namespace { const int32_t DEFAULT_POLLING_INTERVAL = 30000; } ThermalHdfConfig& ThermalHdfConfig::GetInstance() { static ThermalHdfConfig instance; return instance; } int32_t ThermalHdfConfig::ThermalHDIConfigInit(const std::string& path) { if (!baseConfig_) { baseConfig_ = std::make_shared<BaseInfoConfig>(); } return ParseThermalHdiXMLConfig(path); } int32_t ThermalHdfConfig::ParseThermalHdiXMLConfig(const std::string& path) { std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr( xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc); if (docPtr == nullptr) { THERMAL_HILOGW(COMP_HDI, "failed to read xml file"); return HDF_ERR_INVALID_OBJECT; } auto rootNode = xmlDocGetRootElement(docPtr.get()); if (rootNode == nullptr) { THERMAL_HILOGE(COMP_HDI, "failed to read root node"); return HDF_ERR_INVALID_OBJECT; } if (!xmlStrcmp(rootNode->name, BAD_CAST"thermal")) { xmlChar* xmlVersion = xmlGetProp(rootNode, BAD_CAST"version"); if (xmlVersion != nullptr) { this->thermal_.version = std::string(reinterpret_cast<char*>(xmlVersion)); xmlFree(xmlVersion); THERMAL_HILOGD(COMP_HDI, "version: %{public}s", this->thermal_.version.c_str()); } xmlChar* xmlProduct = xmlGetProp(rootNode, BAD_CAST"product"); if (xmlProduct != nullptr) { this->thermal_.product = std::string(reinterpret_cast<char*>(xmlProduct)); xmlFree(xmlProduct); THERMAL_HILOGD(COMP_HDI, "product: %{public}s", this->thermal_.product.c_str()); } } for (auto node = rootNode->children; node; node = node->next) { if (node == nullptr) { continue; } if (!xmlStrcmp(node->name, BAD_CAST"base")) { ParseBaseNode(node); } else if (!xmlStrcmp(node->name, BAD_CAST"polling")) { ParsePollingNode(node); } else if (!xmlStrcmp(node->name, BAD_CAST"tracing")) { ParseTracingNode(node); } else if (!xmlStrcmp(node->name, BAD_CAST"isolate")) { ParseIsolateNode(node); } } return HDF_SUCCESS; } void ThermalHdfConfig::ParseBaseNode(xmlNodePtr node) { auto cur = node->xmlChildrenNode; std::vector<BaseItem> vBase; while (cur != nullptr) { BaseItem item; xmlChar* xmlTag = xmlGetProp(cur, BAD_CAST"tag"); if (xmlTag != nullptr) { item.tag = std::string(reinterpret_cast<char*>(xmlTag)); xmlFree(xmlTag); THERMAL_HILOGD(COMP_HDI, "ParseBaseNode tag: %{public}s", item.tag.c_str()); } xmlChar* xmlValue = xmlGetProp(cur, BAD_CAST"value"); if (xmlValue != nullptr) { item.value = std::string(reinterpret_cast<char*>(xmlValue)); xmlFree(xmlValue); THERMAL_HILOGD(COMP_HDI, "ParseBaseNode value: %{public}s", item.value.c_str()); } vBase.push_back(item); cur = cur->next; } baseConfig_->SetBase(vBase); } std::string ThermalHdfConfig::GetXmlNodeName(xmlNodePtr node, std::string &defaultName) { std::string name; xmlChar* xmlName = xmlGetProp(node, BAD_CAST"name"); if (xmlName == nullptr) { return defaultName; } name = std::string(reinterpret_cast<char*>(xmlName)); xmlFree(xmlName); return name; } void ThermalHdfConfig::ParsePollingNode(xmlNodePtr node) { std::string pollingDefaultName("thermal"); std::string pollingName = GetXmlNodeName(node, pollingDefaultName); GroupMap groupMap; auto cur = node->xmlChildrenNode; while (cur != nullptr) { std::shared_ptr<SensorInfoConfig> sensorInfo = std::make_shared<SensorInfoConfig>(); std::string groupDefaultName("actual"); std::string groupName = GetXmlNodeName(cur, groupDefaultName); sensorInfo->SetGroupName(groupName); THERMAL_HILOGD(COMP_HDI, "ParsePollingNode groupName: %{public}s", groupName.c_str()); xmlChar* xmlInterval = xmlGetProp(cur, BAD_CAST"interval"); if (xmlInterval != nullptr) { std::string strInterval = reinterpret_cast<char *>(xmlInterval); int32_t interval = DEFAULT_POLLING_INTERVAL; StrToInt(TrimStr(strInterval), interval); xmlFree(xmlInterval); THERMAL_HILOGD(COMP_HDI, "ParsePollingNode interval: %{public}d", interval); sensorInfo->SetGroupInterval(interval); } std::vector<XMLThermalZoneInfo> xmlTzInfoList; std::vector<XMLThermalNodeInfo> xmlTnInfoList; for (auto subNode = cur->children; subNode; subNode = subNode->next) { if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_zone")) { XMLThermalZoneInfo tz; GetThermalZoneNodeInfo(tz, subNode); THERMAL_HILOGI(COMP_HDI, "ParsePollingNode ParsePollingNodetztype: %{public}s, replace: %{public}s", tz.type.c_str(), tz.replace.c_str()); xmlTzInfoList.push_back(tz); } else if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) { XMLThermalNodeInfo tn; ParsePollingSubNode(subNode, tn); THERMAL_HILOGI(COMP_HDI, "ParsePollingNode tntype: %{public}s", tn.type.c_str()); xmlTnInfoList.push_back(tn); } } sensorInfo->SetXMLThermalZoneInfo(xmlTzInfoList); sensorInfo->SetXMLThermalNodeInfo(xmlTnInfoList); groupMap.insert(std::make_pair(groupName, sensorInfo)); cur = cur->next; } pollingMap_.insert(std::make_pair(pollingName, groupMap)); } void ThermalHdfConfig::ParsePollingSubNode(xmlNodePtr node, XMLThermalNodeInfo& tn) { DfxTraceInfo info; xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type"); if (xmlType != nullptr) { tn.type = std::string(reinterpret_cast<char*>(xmlType)); xmlFree(xmlType); } xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path"); if (xmlPath != nullptr) { tn.path = std::string(reinterpret_cast<char*>(xmlPath)); xmlFree(xmlPath); } } void ThermalHdfConfig::ParseTracingNode(xmlNodePtr node) { xmlChar* xmlOutpath = xmlGetProp(node, BAD_CAST"outpath"); if (xmlOutpath != nullptr) { if (strcmp(reinterpret_cast<char *>(xmlOutpath), "/data/log/thermal/thermal-log") == 0) { this->traceConfig_.outPath = std::string(reinterpret_cast<char *>(xmlOutpath)); xmlFree(xmlOutpath); } else { THERMAL_HILOGE(COMP_HDI, "xmlOutpath is not /data/log/thermal/thermal-log"); } } auto cur = node->xmlChildrenNode; while (cur != nullptr) { ParseTracingSubNode(cur); cur = cur->next; } } void ThermalHdfConfig::ParseTracingSubNode(xmlNodePtr node) { std::string title; DfxTraceInfo info; std::string valuePath; for (auto subNode = node->children; subNode != nullptr; subNode = subNode->next) { if (!xmlStrcmp(subNode->name, BAD_CAST"title")) { xmlChar* titlePath = xmlGetProp(subNode, BAD_CAST"path"); if (titlePath != nullptr) { ThermalHdfUtils::ReadNode( std::string(reinterpret_cast<char*>(titlePath)), title); xmlFree(titlePath); } xmlChar* titleName = xmlGetProp(subNode, BAD_CAST"name"); if (titleName != nullptr) { title = std::string(reinterpret_cast<char*>(titleName)); xmlFree(titleName); } } if (!xmlStrcmp(subNode->name, BAD_CAST"value")) { xmlChar* xmlValuePath = xmlGetProp(subNode, BAD_CAST"path"); if (xmlValuePath != nullptr) { valuePath = std::string(reinterpret_cast<char*>(xmlValuePath)); xmlFree(xmlValuePath); } } } info.title = title; info.valuePath = valuePath; traceInfo_.emplace_back(info); for (const auto& item : traceInfo_) { THERMAL_HILOGD(COMP_HDI, "item.title = %{public}s", item.title.c_str()); } } void ThermalHdfConfig::GetThermalZoneNodeInfo(XMLThermalZoneInfo& tz, const xmlNode* node) { xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type"); if (xmlType != nullptr) { tz.type = std::string(reinterpret_cast<char*>(xmlType)); xmlFree(xmlType); } auto replace = xmlGetProp(node, BAD_CAST("replace")); if (replace != nullptr) { tz.replace = std::string(reinterpret_cast<char*>(replace)); tz.isReplace = true; xmlFree(replace); } } void ThermalHdfConfig::ParseIsolateNode(xmlNodePtr node) { THERMAL_HILOGD(COMP_HDI, "in"); auto cur = node->xmlChildrenNode; while (cur != nullptr) { std::shared_ptr<IsolateInfoConfig> isolateInfo = std::make_shared<IsolateInfoConfig>(); std::string groupName; xmlChar* xmlName = xmlGetProp(cur, BAD_CAST"name"); if (xmlName != nullptr) { groupName = std::string(reinterpret_cast<char*>(xmlName)); xmlFree(xmlName); isolateInfo->SetGroupName(groupName); THERMAL_HILOGD(COMP_HDI, "groupName: %{public}s", groupName.c_str()); } std::vector<IsolateNodeInfo> xmlTnInfoList; for (auto subNode = cur->children; subNode; subNode = subNode->next) { if (!xmlStrcmp(subNode->name, BAD_CAST"thermal_node")) { IsolateNodeInfo tn; ParseIsolateSubNode(subNode, tn); xmlTnInfoList.push_back(tn); } } isolateInfo->SetIsolateNodeInfo(xmlTnInfoList); isolateInfoMap_.insert(std::make_pair(groupName, isolateInfo)); cur = cur->next; } } void ThermalHdfConfig::ParseIsolateSubNode(xmlNodePtr node, IsolateNodeInfo& tn) { xmlChar* xmlType = xmlGetProp(node, BAD_CAST"type"); if (xmlType != nullptr) { tn.type = std::string(reinterpret_cast<char*>(xmlType)); THERMAL_HILOGD(COMP_HDI, "type: %{public}s", tn.type.c_str()); xmlFree(xmlType); } xmlChar* xmlPath = xmlGetProp(node, BAD_CAST"path"); if (xmlPath != nullptr) { tn.path = std::string(reinterpret_cast<char*>(xmlPath)); THERMAL_HILOGD(COMP_HDI, "path: %{public}s", tn.path.c_str()); xmlFree(xmlPath); } } int32_t ThermalHdfConfig::GetIsolateCpuNodePath(bool isSim, const std::string &type, std::string &path) { std::string groupName = isSim ? "sim" : "actual"; THERMAL_HILOGI(COMP_HDI, "isSim %d, type %{public}s, groupName %{public}s", isSim, type.c_str(), groupName.c_str()); auto mapIter = isolateInfoMap_.find(groupName); if (mapIter == isolateInfoMap_.end()) { THERMAL_HILOGE(COMP_HDI, "failed to get group %s config", groupName.c_str()); return HDF_FAILURE; } std::vector<IsolateNodeInfo> nodeVector = mapIter->second->GetIsolateNodeInfo(); for (auto nodeIter : nodeVector) { if (type == nodeIter.type) { path = nodeIter.path; THERMAL_HILOGI(COMP_HDI, "path %{public}s", path.c_str()); return HDF_SUCCESS; } } THERMAL_HILOGE(COMP_HDI, "failed to get type %{public}s path", type.c_str()); return HDF_FAILURE; } } // V1_1 } // Thermal } // HDI } // OHOS