diff --git a/bundle.json b/bundle.json index 0432c0f9677afa9d0f18be3abeb07c7fb267878a..b7bbc45850d5c0b9174fa10fa086d91c1ea448c3 100644 --- a/bundle.json +++ b/bundle.json @@ -25,12 +25,14 @@ "ability_runtime", "access_token", "c_utils", + "config_policy", "frame_aware_sched", "hilog", "hitrace", "init", "ipc", "jsoncpp", + "libxml2", "safwk", "samgr" ], @@ -45,7 +47,8 @@ "//foundation/resourceschedule/qos_manager/services:concurrentsvc", "//foundation/resourceschedule/qos_manager/frameworks/concurrent_task_client:concurrent_task_client", "//foundation/resourceschedule/qos_manager/qos:qos", - "//foundation/resourceschedule/qos_manager/frameworks/native:qos_ndk" + "//foundation/resourceschedule/qos_manager/frameworks/native:qos_ndk", + "//foundation/resourceschedule/qos_manager/profiles:qos_manager_config" ], "inner_kits": [ { diff --git a/common/include/config_reader.h b/common/include/config_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..729f712602cb52675db79879cee65fc1d7f3e26a --- /dev/null +++ b/common/include/config_reader.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 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. + */ +#ifndef CONCURRENT_TASK_SERVICES_COMMON_INCLUDE_CONFIG_READER_H +#define CONCURRENT_TASK_SERVICES_COMMON_INCLUDE_CONFIG_READER_H + +#include +#include +#include +#include "libxml/parser.h" +#include "libxml/xpath.h" + +namespace OHOS { +namespace ConcurrentTask { +class ConfigReader { +public: + bool LoadFromConfigFile(const std::string& configFile); + void GetRealConfigPath(const char* configName, std::string& configPath); + std::unordered_set authProcUidConfigs_; + std::unordered_set authProcBundleNameConfigs_; +private: + static bool IsValidNode(const xmlNode* currNode); + bool FillinUidInfo(const xmlNode* currNode); + bool FillinBundleNameInfo(const xmlNode* currNode); + void ParseAuth(const xmlNode* currNode); +}; +} // namespace ConcurrentTask +} // namespace OHOS +#endif // CONCURRENT_TASK_SERVICES_COMMON_INCLUDE_CONFIG_READER_H diff --git a/common/src/config_reader.cpp b/common/src/config_reader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39a7b046842c553dd60db78a2eaf5124d3c10f44 --- /dev/null +++ b/common/src/config_reader.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2024 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 +#include +#include "config_reader.h" +#include "config_policy_utils.h" +#include "concurrent_task_log.h" + +using namespace std; + +namespace OHOS { +namespace ConcurrentTask { +namespace { + const std::string XML_TAG_QOS_CONFIG = "qosconfig"; + const std::string XML_TAG_QOS_AUTH = "auth"; + const std::string XML_TAG_UIDLIST = "uidlist"; + const std::string XML_TAG_UID = "uid"; + const std::string XML_TAG_BUNDLENAMELIST = "bundlenamelist"; + const std::string XML_TAG_BUNDLENAME = "bundlename"; +} + +bool ConfigReader::IsValidNode(const xmlNode* currNode) +{ + if (!currNode->name || currNode->type == XML_COMMENT_NODE) { + return false; + } + return true; +} + +bool ConfigReader::FillinUidInfo(const xmlNode* currNode) +{ + xmlNodePtr currNodePtr = currNode->xmlChildrenNode; + for (; currNodePtr; currNodePtr = currNodePtr->next) { + if (xmlStrcmp(currNodePtr->name, reinterpret_cast(XML_TAG_UID.c_str())) == 0) { + xmlChar *attrValue = xmlGetProp(currNodePtr, reinterpret_cast(XML_TAG_UID.c_str())); + if (!attrValue) { + CONCUR_LOGW("FillinUidInfo uid null!"); + return false; + } + int64_t uid = atoi(reinterpret_cast(attrValue)); + authProcUidConfigs_.insert(uid); + xmlFree(attrValue); + } + } + return true; +} + +bool ConfigReader::FillinBundleNameInfo(const xmlNode* currNode) +{ + xmlNodePtr currNodePtr = currNode->xmlChildrenNode; + for (; currNodePtr; currNodePtr = currNodePtr->next) { + if (xmlStrcmp(currNodePtr->name, reinterpret_cast(XML_TAG_BUNDLENAME.c_str())) == 0) { + xmlChar *attrValue = xmlGetProp(currNodePtr, reinterpret_cast(XML_TAG_BUNDLENAME.c_str())); + if (!attrValue) { + CONCUR_LOGW("FillinBundleNameInfo bundleName null!"); + return false; + } + std::string bundleName = reinterpret_cast(attrValue); + authProcBundleNameConfigs_.insert(bundleName); + xmlFree(attrValue); + } + } + return true; +} + +void ConfigReader::ParseAuth(const xmlNode* currNode) +{ + xmlNodePtr currNodePtr = currNode->xmlChildrenNode; + for (; currNodePtr; currNodePtr = currNodePtr->next) { + if (xmlStrcmp(currNodePtr->name, reinterpret_cast(XML_TAG_UIDLIST.c_str())) == 0) { + if (!FillinUidInfo(currNodePtr)) { + CONCUR_LOGE("uid fill in authProcUidConfigs_ error!"); + continue; + } + } + + if (xmlStrcmp(currNodePtr->name, reinterpret_cast(XML_TAG_BUNDLENAMELIST.c_str())) == 0) { + if (!FillinBundleNameInfo(currNodePtr)) { + CONCUR_LOGE("bundleName fill in authProcBundleNameConfigs_ error!"); + continue; + } + } + } +} + +bool ConfigReader::LoadFromConfigFile(const std::string& configFile) +{ + // skip the empty string, else you will get empty node + xmlDocPtr xmlDocPtr = xmlReadFile(configFile.c_str(), nullptr, + XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING); + if (!xmlDocPtr) { + CONCUR_LOGE("xmlReadFile error!"); + return false; + } + xmlNodePtr rootNodePtr = xmlDocGetRootElement(xmlDocPtr); + if (!rootNodePtr || !rootNodePtr->name || + xmlStrcmp(rootNodePtr->name, reinterpret_cast(XML_TAG_QOS_CONFIG.c_str())) != 0) { + CONCUR_LOGE("root element tag error!"); + xmlFreeDoc(xmlDocPtr); + return false; + } + xmlNodePtr currNodePtr = rootNodePtr->xmlChildrenNode; + for (; currNodePtr; currNodePtr = currNodePtr->next) { + if (!IsValidNode(currNodePtr)) { + continue; + } + if (xmlStrcmp(currNodePtr->name, reinterpret_cast(XML_TAG_QOS_AUTH.c_str())) == 0) { + ParseAuth(currNodePtr); + } + } + xmlFreeDoc(xmlDocPtr); + return true; +} + +void ConfigReader::GetRealConfigPath(const char* configName, std::string& configPath) +{ + char buf[PATH_MAX + 1] = {0}; + char* configFilePath = GetOneCfgFile(configName, buf, PATH_MAX + 1); + char tmpPath[PATH_MAX + 1] = {0}; + if (!configFilePath || strlen(configFilePath) == 0 || strlen(configFilePath) > PATH_MAX || + !realpath(configFilePath, tmpPath)) { + CONCUR_LOGE("get config file path error!"); + configPath = ""; + return; + } + configPath = tmpPath; +} +} +} \ No newline at end of file diff --git a/profiles/BUILD.gn b/profiles/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b76467d8810aec1b8959201ccd65bf628b71194b --- /dev/null +++ b/profiles/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2024 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. + +import("//build/ohos.gni") + +ohos_prebuilt_etc("qos_manager_config") { + source = "qos_manager_config.xml" + install_enable = true + subsystem_name = "resourceschedule" + part_name = "qos_manager" + module_install_dir = "etc/qos_manager" +} \ No newline at end of file diff --git a/profiles/qos_manager_config.xml b/profiles/qos_manager_config.xml new file mode 100644 index 0000000000000000000000000000000000000000..019882b91a8f7bfe969b47e67d7821d42e373f04 --- /dev/null +++ b/profiles/qos_manager_config.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/qos/qos.cpp b/qos/qos.cpp index fc928a6899aa17bf845996ee14106a4a994673dd..6c6d91f7a87a3f995a55ccce195ad2dfde8ae0f3 100644 --- a/qos/qos.cpp +++ b/qos/qos.cpp @@ -16,7 +16,9 @@ #include #include #include "concurrent_task_log.h" +#if !defined(CROSS_PLATFORM) #include "parameters.h" +#endif #include "qos_interface.h" #include "qos.h" using namespace OHOS::ConcurrentTask; @@ -33,12 +35,14 @@ QosController& QosController::GetInstance() int QosController::SetThreadQosForOtherThread(enum QosLevel level, int tid) { +#if !defined(CROSS_PLATFORM) bool qosEnable = OHOS::system::GetBoolParameter("persist.all.setQos.on", true); - int qos = static_cast(level); if (!qosEnable) { - CONCUR_LOGD("[Qos] qoslevel %{public}d apply for tid %{public}d disable", qos, tid); + CONCUR_LOGD("[Qos] qoslevel %{public}d apply for tid %{public}d disable", static_cast(level), tid); return 0; } +#endif + int qos = static_cast(level); if (level < QosLevel::QOS_BACKGROUND || level >= QosLevel::QOS_MAX) { CONCUR_LOGE("[Qos] invalid qos level %{public}d", qos); return ERROR_NUM; @@ -55,11 +59,13 @@ int QosController::SetThreadQosForOtherThread(enum QosLevel level, int tid) int QosController::ResetThreadQosForOtherThread(int tid) { +#if !defined(CROSS_PLATFORM) bool qosEnable = OHOS::system::GetBoolParameter("persist.all.setQos.on", true); if (!qosEnable) { CONCUR_LOGD("[Qos] qoslevel reset disable for tid %{public}d.", tid); return 0; } +#endif int ret = QosLeaveForOther(tid); if (ret == 0) { CONCUR_LOGD("[Qos] qoslevel reset for tid %{public}d success", tid); diff --git a/services/BUILD.gn b/services/BUILD.gn index f37216f3fceaa9bca918b16b5dfefff3ea746caf..79eb829126918d90047e87c6d9917a3292a09a6d 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -25,6 +25,7 @@ config("concurrent_task_config") { "../include", "../frameworks/concurrent_task_client/include/", "../interfaces/inner_api/", + "../common/include", ] } @@ -43,6 +44,7 @@ ohos_shared_library("concurrentsvc") { "src/concurrent_task_service_stub.cpp", "src/qos_interface.cpp", "src/qos_policy.cpp", + "../common/src/config_reader.cpp", ] deps = [ "../etc/param:ffrt_etc" ] @@ -55,9 +57,11 @@ ohos_shared_library("concurrentsvc") { external_deps = [ "access_token:libaccesstoken_sdk", "c_utils:utils", + "config_policy:configpolicy_util", "frame_aware_sched:rtg_interface", "hilog:libhilog", "hitrace:hitrace_meter", + "libxml2:libxml2", "init:libbegetutil", "ipc:ipc_single", "jsoncpp:jsoncpp", diff --git a/services/include/concurrent_task_controller.h b/services/include/concurrent_task_controller.h index 7f4c321fc11d8d84fb83b893daadf65eb9ed5f6d..f65ffe8a4e87e536166aa71f175f466f638bac49 100644 --- a/services/include/concurrent_task_controller.h +++ b/services/include/concurrent_task_controller.h @@ -24,6 +24,7 @@ #include #include "json/json.h" #include "concurrent_task_type.h" +#include "config_reader.h" #include "qos_policy.h" namespace OHOS { @@ -68,6 +69,7 @@ private: void ContinuousTaskProcess(int uid, int pid, int status); void FocusStatusProcess(int uid, int pid, int status); int AuthSystemProcess(int pid); + void ConfigReaderInit(); bool ModifySystemRate(const Json::Value& payload); void SetAppRate(const Json::Value& payload); int FindRateFromInfo(int uiTid, const Json::Value& payload); @@ -99,10 +101,12 @@ private: int hardwareTid_ = -1; int systemRate_ = 0; bool rtgEnabled_ = false; + bool configEnable_ = false; bool rsAuthed_ = false; std::atomic curGamePid_ = -1; int executorNum_ = 0; std::map appBundleName; + std::unique_ptr ConfigReader_ = nullptr; const std::string RENDER_SERVICE_PROCESS_NAME = "render_service"; const std::string RESOURCE_SCHEDULE_PROCESS_NAME = "resource_schedule_service"; diff --git a/services/src/concurrent_task_controller.cpp b/services/src/concurrent_task_controller.cpp index 3df8bb1a456ec1e2da9dc773a331f173452b52c6..a1bf3c82a6fde2e80b8fcb9308532299c1804010 100644 --- a/services/src/concurrent_task_controller.cpp +++ b/services/src/concurrent_task_controller.cpp @@ -36,6 +36,7 @@ namespace { const std::string INTERVAL_DDL = "persist.ffrt.interval.renderthread"; const std::string INTERVAL_APP_RATE = "persist.ffrt.interval.appRate"; const std::string INTERVAL_RS_RATE = "persist.ffrt.interval.rsRate"; + const std::string CONFIG_FILE_NAME = "etc/qos_manager/qos_manager_config.xml"; constexpr int CURRENT_RATE = 120; constexpr int PARAM_TYPE = 1; constexpr int UNI_APP_RATE_ID = -1; @@ -56,9 +57,15 @@ TaskController& TaskController::GetInstance() void TaskController::RequestAuth(const Json::Value& payload) { + if (!configEnable_) { + ConfigReaderInit(); + } pid_t uid = IPCSkeleton::GetInstance().GetCallingUid(); - if (uid != HWF_SERVICE_UID) { - CONCUR_LOGE("Invalid uid %{public}d, only hwf service uid can call RequestAuth", uid); + auto uidIter = ConfigReader_->authProcUidConfigs_.find(uid); + auto bundleNameIter = ConfigReader_->authProcBundleNameConfigs_.find(GetProcessNameByToken()); + if (uidIter == ConfigReader_->authProcUidConfigs_.end() && + bundleNameIter == ConfigReader_->authProcBundleNameConfigs_.end()) { + CONCUR_LOGE("Invalid uid %{public}d, only hwf service uid and msdp can call RequestAuth", uid); return; } pid_t pid = IPCSkeleton::GetInstance().GetCallingPid(); @@ -320,6 +327,24 @@ void TaskController::Init() TypeMapInit(); qosPolicy_.Init(); TryCreateRsGroup(); + ConfigReaderInit(); +} + +void TaskController::ConfigReaderInit() +{ + ConfigReader_ = make_unique(); + if (!ConfigReader_) { + CONCUR_LOGE("ConfigReader_ initialize error!"); + return; + } + + std::string realPath; + ConfigReader_->GetRealConfigPath(CONFIG_FILE_NAME.c_str(), realPath); + if (realPath.empty() || !ConfigReader_->LoadFromConfigFile(realPath)) { + CONCUR_LOGE("config load failed!"); + return; + } + configEnable_ = true; } void TaskController::Release() @@ -333,6 +358,7 @@ void TaskController::Release() DestroyRtgGrp(renderServiceRenderGrpId_); renderServiceRenderGrpId_ = -1; } + ConfigReader_ = nullptr; } void TaskController::TypeMapInit()