15ccb8f90Sopenharmony_ci/*
25ccb8f90Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
35ccb8f90Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
45ccb8f90Sopenharmony_ci * you may not use this file except in compliance with the License.
55ccb8f90Sopenharmony_ci * You may obtain a copy of the License at
65ccb8f90Sopenharmony_ci *
75ccb8f90Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
85ccb8f90Sopenharmony_ci *
95ccb8f90Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
105ccb8f90Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
115ccb8f90Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125ccb8f90Sopenharmony_ci * See the License for the specific language governing permissions and
135ccb8f90Sopenharmony_ci * limitations under the License.
145ccb8f90Sopenharmony_ci */
155ccb8f90Sopenharmony_ci
165ccb8f90Sopenharmony_ci#include "power_save_mode.h"
175ccb8f90Sopenharmony_ci
185ccb8f90Sopenharmony_ci#include "libxml/parser.h"
195ccb8f90Sopenharmony_ci
205ccb8f90Sopenharmony_ci#include "config_policy_utils.h"
215ccb8f90Sopenharmony_ci#include "power_log.h"
225ccb8f90Sopenharmony_ci#include "string_ex.h"
235ccb8f90Sopenharmony_ci
245ccb8f90Sopenharmony_cinamespace OHOS {
255ccb8f90Sopenharmony_cinamespace PowerMgr {
265ccb8f90Sopenharmony_cinamespace {
275ccb8f90Sopenharmony_ciconst std::string TAG_ROOT = "switch_policy";
285ccb8f90Sopenharmony_ciconst std::string POWER_MODE_CONFIG_PATH = "etc/power_config/power_mode_config.xml";
295ccb8f90Sopenharmony_ciconst std::string VENDOR_POWER_MODE_CONFIG_PATH = "/vendor/etc/power_config/power_mode_config.xml";
305ccb8f90Sopenharmony_ciconst std::string SYSTEM_POWER_MODE_CONFIG_PATH = "/system/etc/power_config/power_mode_config.xml";
315ccb8f90Sopenharmony_ciconstexpr uint32_t SLEEP_FILTER = SLEEP_FILTER_VALUE;
325ccb8f90Sopenharmony_ci}
335ccb8f90Sopenharmony_ci
345ccb8f90Sopenharmony_ciPowerSaveMode::PowerSaveMode()
355ccb8f90Sopenharmony_ci{
365ccb8f90Sopenharmony_ci    POWER_HILOGD(FEATURE_POWER_MODE, "Start to parse power_mode_config.xml");
375ccb8f90Sopenharmony_ci
385ccb8f90Sopenharmony_ci    char buf[MAX_PATH_LEN];
395ccb8f90Sopenharmony_ci    char* path = GetOneCfgFile(POWER_MODE_CONFIG_PATH.c_str(), buf, MAX_PATH_LEN);
405ccb8f90Sopenharmony_ci    if (path != nullptr && *path != '\0') {
415ccb8f90Sopenharmony_ci        if (!StartXMlParse(path)) {
425ccb8f90Sopenharmony_ci            POWER_HILOGE(FEATURE_POWER_MODE, "policy config file power_mode_config.xml err");
435ccb8f90Sopenharmony_ci        }
445ccb8f90Sopenharmony_ci        return;
455ccb8f90Sopenharmony_ci    }
465ccb8f90Sopenharmony_ci
475ccb8f90Sopenharmony_ci    if (!StartXMlParse(VENDOR_POWER_MODE_CONFIG_PATH)) {
485ccb8f90Sopenharmony_ci        POWER_HILOGI(FEATURE_POWER_MODE, "No vendor power_mode_config.xml, start to parse system config");
495ccb8f90Sopenharmony_ci        StartXMlParse(SYSTEM_POWER_MODE_CONFIG_PATH);
505ccb8f90Sopenharmony_ci    }
515ccb8f90Sopenharmony_ci}
525ccb8f90Sopenharmony_ci
535ccb8f90Sopenharmony_cibool IsNodeLegal(const xmlNodePtr nodePtr, const std::string& tagName)
545ccb8f90Sopenharmony_ci{
555ccb8f90Sopenharmony_ci    return nodePtr != nullptr && nodePtr->type != XML_COMMENT_NODE && nodePtr->name != nullptr &&
565ccb8f90Sopenharmony_ci    xmlStrEqual(nodePtr->name, BAD_CAST(tagName.c_str())) == 0;
575ccb8f90Sopenharmony_ci}
585ccb8f90Sopenharmony_ci
595ccb8f90Sopenharmony_cibool PowerSaveMode::StartXMlParse(std::string path)
605ccb8f90Sopenharmony_ci{
615ccb8f90Sopenharmony_ci    std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
625ccb8f90Sopenharmony_ci        xmlReadFile(path.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
635ccb8f90Sopenharmony_ci    if (docPtr == nullptr) {
645ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_POWER_MODE, "Parse failed, read file failed.");
655ccb8f90Sopenharmony_ci        return false;
665ccb8f90Sopenharmony_ci    }
675ccb8f90Sopenharmony_ci
685ccb8f90Sopenharmony_ci    auto rootPtr = xmlDocGetRootElement(docPtr.get());
695ccb8f90Sopenharmony_ci    if (!IsNodeLegal(rootPtr, TAG_ROOT)) {
705ccb8f90Sopenharmony_ci        POWER_HILOGE(FEATURE_POWER_MODE, "Parse failed, root node is illegal.");
715ccb8f90Sopenharmony_ci        return false;
725ccb8f90Sopenharmony_ci    }
735ccb8f90Sopenharmony_ci
745ccb8f90Sopenharmony_ci    for (auto nodePtr = rootPtr->xmlChildrenNode; nodePtr != nullptr; nodePtr = nodePtr->next) {
755ccb8f90Sopenharmony_ci        int32_t policyId = 0;
765ccb8f90Sopenharmony_ci        StrToInt(TrimStr(GetProp(nodePtr, "id")), policyId);
775ccb8f90Sopenharmony_ci        POWER_HILOGD(FEATURE_POWER_MODE, "policyId: %{public}d.", policyId);
785ccb8f90Sopenharmony_ci        std::list<ModePolicy> listPolicy;
795ccb8f90Sopenharmony_ci        for (auto policyNodePtr = nodePtr->xmlChildrenNode;
805ccb8f90Sopenharmony_ci            policyNodePtr != nullptr; policyNodePtr = policyNodePtr->next) {
815ccb8f90Sopenharmony_ci            ModePolicy pmp;
825ccb8f90Sopenharmony_ci            int32_t switchId;
835ccb8f90Sopenharmony_ci            StrToInt(TrimStr(GetProp(policyNodePtr, "id")), switchId);
845ccb8f90Sopenharmony_ci            StrToInt(TrimStr(GetProp(policyNodePtr, "recover_flag")), pmp.recover_flag);
855ccb8f90Sopenharmony_ci            StrToInt(TrimStr(GetProp(policyNodePtr, "value")), pmp.value);
865ccb8f90Sopenharmony_ci            pmp.id = static_cast<uint32_t>(switchId);
875ccb8f90Sopenharmony_ci            listPolicy.push_back(pmp);
885ccb8f90Sopenharmony_ci            POWER_HILOGD(FEATURE_POWER_MODE, "id=%{public}d, value=%{public}d, recover_flag=%{public}d", pmp.id,
895ccb8f90Sopenharmony_ci                pmp.value, pmp.recover_flag);
905ccb8f90Sopenharmony_ci        }
915ccb8f90Sopenharmony_ci        std::pair<uint32_t, std::list<ModePolicy>> policyPair(policyId, listPolicy);
925ccb8f90Sopenharmony_ci        this->policyCache_.insert(policyPair);
935ccb8f90Sopenharmony_ci    }
945ccb8f90Sopenharmony_ci    return true;
955ccb8f90Sopenharmony_ci}
965ccb8f90Sopenharmony_ci
975ccb8f90Sopenharmony_cistd::string PowerSaveMode::GetProp(const xmlNodePtr& nodePtr, const std::string& key)
985ccb8f90Sopenharmony_ci{
995ccb8f90Sopenharmony_ci    xmlChar* prop = xmlGetProp(nodePtr, BAD_CAST(key.c_str()));
1005ccb8f90Sopenharmony_ci    if (prop == nullptr) {
1015ccb8f90Sopenharmony_ci        return "";
1025ccb8f90Sopenharmony_ci    }
1035ccb8f90Sopenharmony_ci    std::string value = reinterpret_cast<char*>(prop);
1045ccb8f90Sopenharmony_ci    xmlFree(prop);
1055ccb8f90Sopenharmony_ci    return value;
1065ccb8f90Sopenharmony_ci}
1075ccb8f90Sopenharmony_ci
1085ccb8f90Sopenharmony_ciint32_t PowerSaveMode::GetSleepTime(int32_t mode)
1095ccb8f90Sopenharmony_ci{
1105ccb8f90Sopenharmony_ci    if (this->policyCache_.size() == 0) {
1115ccb8f90Sopenharmony_ci        return RETURN_FLAG_FALSE;
1125ccb8f90Sopenharmony_ci    }
1135ccb8f90Sopenharmony_ci    std::list<ModePolicy>& modePolicyList = this->policyCache_[mode];
1145ccb8f90Sopenharmony_ci    const auto& itemPolicy = std::find_if(modePolicyList.begin(), modePolicyList.end(), [](const auto& modePolicy) {
1155ccb8f90Sopenharmony_ci        return modePolicy.id == SLEEP_FILTER;
1165ccb8f90Sopenharmony_ci    });
1175ccb8f90Sopenharmony_ci
1185ccb8f90Sopenharmony_ci    return (itemPolicy != modePolicyList.end()) ? itemPolicy->value : RETURN_FLAG_FALSE;
1195ccb8f90Sopenharmony_ci}
1205ccb8f90Sopenharmony_ci} // namespace PowerMgr
1215ccb8f90Sopenharmony_ci} // namespace OHOS
122