13fc297bdSopenharmony_ci/* 23fc297bdSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 33fc297bdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43fc297bdSopenharmony_ci * you may not use this file except in compliance with the License. 53fc297bdSopenharmony_ci * You may obtain a copy of the License at 63fc297bdSopenharmony_ci * 73fc297bdSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83fc297bdSopenharmony_ci * 93fc297bdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103fc297bdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113fc297bdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123fc297bdSopenharmony_ci * See the License for the specific language governing permissions and 133fc297bdSopenharmony_ci * limitations under the License. 143fc297bdSopenharmony_ci */ 153fc297bdSopenharmony_ci 163fc297bdSopenharmony_ci#include "socperf_stub.h" 173fc297bdSopenharmony_ci#include "accesstoken_kit.h" 183fc297bdSopenharmony_ci#include "ipc_skeleton.h" 193fc297bdSopenharmony_ci#include "parameters.h" 203fc297bdSopenharmony_ci#include "socperf_ipc_interface_code.h" 213fc297bdSopenharmony_ci#include "socperf_log.h" 223fc297bdSopenharmony_ci#include "tokenid_kit.h" 233fc297bdSopenharmony_ci 243fc297bdSopenharmony_cinamespace OHOS { 253fc297bdSopenharmony_cinamespace SOCPERF { 263fc297bdSopenharmony_cinamespace { 273fc297bdSopenharmony_ci constexpr int32_t HIVIEW_UID = 1201; 283fc297bdSopenharmony_ci constexpr int32_t MSG_STRING_MAX_LEN = 1024; 293fc297bdSopenharmony_ci constexpr int32_t MSG_VECTOR_MAX_LEN = 1024; 303fc297bdSopenharmony_ci constexpr int32_t MSG_VECTOR_INVALID_LEN = 0; 313fc297bdSopenharmony_ci const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0); 323fc297bdSopenharmony_ci} 333fc297bdSopenharmony_ciint32_t SocPerfStub::OnRemoteRequest(uint32_t code, MessageParcel &data, 343fc297bdSopenharmony_ci MessageParcel &reply, MessageOption &option) 353fc297bdSopenharmony_ci{ 363fc297bdSopenharmony_ci auto remoteDescriptor = data.ReadInterfaceToken(); 373fc297bdSopenharmony_ci if (GetDescriptor() != remoteDescriptor || !HasPerfPermission()) { 383fc297bdSopenharmony_ci return ERR_INVALID_STATE; 393fc297bdSopenharmony_ci } 403fc297bdSopenharmony_ci 413fc297bdSopenharmony_ci int32_t ret = ERR_OK; 423fc297bdSopenharmony_ci switch (code) { 433fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_PERF_REQUEST): { 443fc297bdSopenharmony_ci ret = StubPerfRequest(data); 453fc297bdSopenharmony_ci break; 463fc297bdSopenharmony_ci } 473fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_PERF_REQUEST_EX): { 483fc297bdSopenharmony_ci ret = StubPerfRequestEx(data); 493fc297bdSopenharmony_ci break; 503fc297bdSopenharmony_ci } 513fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ): { 523fc297bdSopenharmony_ci ret = StubPowerLimitBoost(data); 533fc297bdSopenharmony_ci break; 543fc297bdSopenharmony_ci } 553fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ): { 563fc297bdSopenharmony_ci ret = StubThermalLimitBoost(data); 573fc297bdSopenharmony_ci break; 583fc297bdSopenharmony_ci } 593fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_LIMIT_REQUEST): { 603fc297bdSopenharmony_ci ret = StubLimitRequest(data); 613fc297bdSopenharmony_ci break; 623fc297bdSopenharmony_ci } 633fc297bdSopenharmony_ci default: 643fc297bdSopenharmony_ci return OnRemoteRequestExt(code, data, reply, option); 653fc297bdSopenharmony_ci } 663fc297bdSopenharmony_ci return ret; 673fc297bdSopenharmony_ci} 683fc297bdSopenharmony_ci 693fc297bdSopenharmony_ciint32_t SocPerfStub::OnRemoteRequestExt(uint32_t code, MessageParcel &data, 703fc297bdSopenharmony_ci MessageParcel &reply, MessageOption &option) 713fc297bdSopenharmony_ci{ 723fc297bdSopenharmony_ci int32_t ret = ERR_OK; 733fc297bdSopenharmony_ci switch (code) { 743fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_SET_STATUS): { 753fc297bdSopenharmony_ci ret = StubSetRequestStatus(data); 763fc297bdSopenharmony_ci break; 773fc297bdSopenharmony_ci } 783fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_SET_THERMAL_LEVEL): { 793fc297bdSopenharmony_ci ret = StubSetThermalLevel(data); 803fc297bdSopenharmony_ci break; 813fc297bdSopenharmony_ci } 823fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_SET_DEVICE_MODE): { 833fc297bdSopenharmony_ci ret = StubRequestDeviceMode(data); 843fc297bdSopenharmony_ci break; 853fc297bdSopenharmony_ci } 863fc297bdSopenharmony_ci case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_REQUEST_CMDID_COUNT): { 873fc297bdSopenharmony_ci ret = StubRequestCmdIdCount(data, reply); 883fc297bdSopenharmony_ci break; 893fc297bdSopenharmony_ci } 903fc297bdSopenharmony_ci default: 913fc297bdSopenharmony_ci return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 923fc297bdSopenharmony_ci } 933fc297bdSopenharmony_ci return ret; 943fc297bdSopenharmony_ci} 953fc297bdSopenharmony_ci 963fc297bdSopenharmony_ciint32_t SocPerfStub::StubPerfRequest(MessageParcel &data) 973fc297bdSopenharmony_ci{ 983fc297bdSopenharmony_ci int32_t cmdId = 0; 993fc297bdSopenharmony_ci if (!data.ReadInt32(cmdId)) { 1003fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read cmdId failed", __func__); 1013fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1023fc297bdSopenharmony_ci } 1033fc297bdSopenharmony_ci 1043fc297bdSopenharmony_ci std::string msg; 1053fc297bdSopenharmony_ci if (!data.ReadString(msg)) { 1063fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__); 1073fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1083fc297bdSopenharmony_ci } 1093fc297bdSopenharmony_ci if (msg.length() > MSG_STRING_MAX_LEN) { 1103fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1113fc297bdSopenharmony_ci } 1123fc297bdSopenharmony_ci 1133fc297bdSopenharmony_ci PerfRequest(cmdId, msg); 1143fc297bdSopenharmony_ci return ERR_OK; 1153fc297bdSopenharmony_ci} 1163fc297bdSopenharmony_ci 1173fc297bdSopenharmony_ciint32_t SocPerfStub::StubPerfRequestEx(MessageParcel &data) 1183fc297bdSopenharmony_ci{ 1193fc297bdSopenharmony_ci int32_t cmdId = 0; 1203fc297bdSopenharmony_ci if (!data.ReadInt32(cmdId)) { 1213fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read cmdId failed", __func__); 1223fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1233fc297bdSopenharmony_ci } 1243fc297bdSopenharmony_ci 1253fc297bdSopenharmony_ci bool onOffTag = false; 1263fc297bdSopenharmony_ci if (!data.ReadBool(onOffTag)) { 1273fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read onOffTag failed", __func__); 1283fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1293fc297bdSopenharmony_ci } 1303fc297bdSopenharmony_ci 1313fc297bdSopenharmony_ci std::string msg; 1323fc297bdSopenharmony_ci if (!data.ReadString(msg)) { 1333fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__); 1343fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1353fc297bdSopenharmony_ci } 1363fc297bdSopenharmony_ci if (msg.length() > MSG_STRING_MAX_LEN) { 1373fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1383fc297bdSopenharmony_ci } 1393fc297bdSopenharmony_ci 1403fc297bdSopenharmony_ci PerfRequestEx(cmdId, onOffTag, msg); 1413fc297bdSopenharmony_ci return ERR_OK; 1423fc297bdSopenharmony_ci} 1433fc297bdSopenharmony_ci 1443fc297bdSopenharmony_ciint32_t SocPerfStub::StubPowerLimitBoost(MessageParcel &data) 1453fc297bdSopenharmony_ci{ 1463fc297bdSopenharmony_ci bool onOffTag = false; 1473fc297bdSopenharmony_ci if (!data.ReadBool(onOffTag)) { 1483fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read onOffTag failed", __func__); 1493fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1503fc297bdSopenharmony_ci } 1513fc297bdSopenharmony_ci 1523fc297bdSopenharmony_ci std::string msg; 1533fc297bdSopenharmony_ci if (!data.ReadString(msg)) { 1543fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__); 1553fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1563fc297bdSopenharmony_ci } 1573fc297bdSopenharmony_ci if (msg.length() > MSG_STRING_MAX_LEN) { 1583fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1593fc297bdSopenharmony_ci } 1603fc297bdSopenharmony_ci 1613fc297bdSopenharmony_ci PowerLimitBoost(onOffTag, msg); 1623fc297bdSopenharmony_ci return ERR_OK; 1633fc297bdSopenharmony_ci} 1643fc297bdSopenharmony_ci 1653fc297bdSopenharmony_ciint32_t SocPerfStub::StubThermalLimitBoost(MessageParcel &data) 1663fc297bdSopenharmony_ci{ 1673fc297bdSopenharmony_ci bool onOffTag = false; 1683fc297bdSopenharmony_ci if (!data.ReadBool(onOffTag)) { 1693fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read onOffTag failed", __func__); 1703fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1713fc297bdSopenharmony_ci } 1723fc297bdSopenharmony_ci 1733fc297bdSopenharmony_ci std::string msg; 1743fc297bdSopenharmony_ci if (!data.ReadString(msg)) { 1753fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__); 1763fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1773fc297bdSopenharmony_ci } 1783fc297bdSopenharmony_ci if (msg.length() > MSG_STRING_MAX_LEN) { 1793fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1803fc297bdSopenharmony_ci } 1813fc297bdSopenharmony_ci 1823fc297bdSopenharmony_ci ThermalLimitBoost(onOffTag, msg); 1833fc297bdSopenharmony_ci return ERR_OK; 1843fc297bdSopenharmony_ci} 1853fc297bdSopenharmony_ci 1863fc297bdSopenharmony_ciint32_t SocPerfStub::StubLimitRequest(MessageParcel &data) 1873fc297bdSopenharmony_ci{ 1883fc297bdSopenharmony_ci int32_t clientId; 1893fc297bdSopenharmony_ci if (!data.ReadInt32(clientId)) { 1903fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read clientId failed", __func__); 1913fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1923fc297bdSopenharmony_ci } 1933fc297bdSopenharmony_ci 1943fc297bdSopenharmony_ci std::vector<int32_t> tags; 1953fc297bdSopenharmony_ci if (!data.ReadInt32Vector(&tags)) { 1963fc297bdSopenharmony_ci SOC_PERF_LOGE("error tags to do StubLimitRequest"); 1973fc297bdSopenharmony_ci return ERR_INVALID_STATE; 1983fc297bdSopenharmony_ci } 1993fc297bdSopenharmony_ci if (tags.size() == MSG_VECTOR_INVALID_LEN || tags.size() > MSG_VECTOR_MAX_LEN) { 2003fc297bdSopenharmony_ci SOC_PERF_LOGE("error tags to do StubLimitRequest"); 2013fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2023fc297bdSopenharmony_ci } 2033fc297bdSopenharmony_ci 2043fc297bdSopenharmony_ci std::vector<int64_t> configs; 2053fc297bdSopenharmony_ci if (!data.ReadInt64Vector(&configs)) { 2063fc297bdSopenharmony_ci SOC_PERF_LOGE("error configs to do StubLimitRequest"); 2073fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2083fc297bdSopenharmony_ci } 2093fc297bdSopenharmony_ci if (configs.size() == MSG_VECTOR_INVALID_LEN || configs.size() > MSG_VECTOR_MAX_LEN) { 2103fc297bdSopenharmony_ci SOC_PERF_LOGE("error configs to do StubLimitRequest"); 2113fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2123fc297bdSopenharmony_ci } 2133fc297bdSopenharmony_ci 2143fc297bdSopenharmony_ci std::string msg; 2153fc297bdSopenharmony_ci if (!data.ReadString(msg)) { 2163fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__); 2173fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2183fc297bdSopenharmony_ci } 2193fc297bdSopenharmony_ci if (msg.length() > MSG_STRING_MAX_LEN) { 2203fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2213fc297bdSopenharmony_ci } 2223fc297bdSopenharmony_ci 2233fc297bdSopenharmony_ci LimitRequest(clientId, tags, configs, msg); 2243fc297bdSopenharmony_ci return ERR_OK; 2253fc297bdSopenharmony_ci} 2263fc297bdSopenharmony_ci 2273fc297bdSopenharmony_ciint32_t SocPerfStub::StubSetRequestStatus(MessageParcel &data) 2283fc297bdSopenharmony_ci{ 2293fc297bdSopenharmony_ci bool requestEnable; 2303fc297bdSopenharmony_ci if (!data.ReadBool(requestEnable)) { 2313fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read requestEnable failed", __func__); 2323fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2333fc297bdSopenharmony_ci } 2343fc297bdSopenharmony_ci 2353fc297bdSopenharmony_ci std::string msg; 2363fc297bdSopenharmony_ci if (!data.ReadString(msg)) { 2373fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__); 2383fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2393fc297bdSopenharmony_ci } 2403fc297bdSopenharmony_ci if (msg.length() > MSG_STRING_MAX_LEN) { 2413fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2423fc297bdSopenharmony_ci } 2433fc297bdSopenharmony_ci 2443fc297bdSopenharmony_ci SetRequestStatus(requestEnable, msg); 2453fc297bdSopenharmony_ci return ERR_OK; 2463fc297bdSopenharmony_ci} 2473fc297bdSopenharmony_ci 2483fc297bdSopenharmony_ciint32_t SocPerfStub::StubSetThermalLevel(MessageParcel &data) 2493fc297bdSopenharmony_ci{ 2503fc297bdSopenharmony_ci int32_t levelId; 2513fc297bdSopenharmony_ci if (!data.ReadInt32(levelId)) { 2523fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read levelId failed", __func__); 2533fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2543fc297bdSopenharmony_ci } 2553fc297bdSopenharmony_ci 2563fc297bdSopenharmony_ci SetThermalLevel(levelId); 2573fc297bdSopenharmony_ci return ERR_OK; 2583fc297bdSopenharmony_ci} 2593fc297bdSopenharmony_ci 2603fc297bdSopenharmony_ciint32_t SocPerfStub::StubRequestDeviceMode(MessageParcel &data) 2613fc297bdSopenharmony_ci{ 2623fc297bdSopenharmony_ci std::string mode; 2633fc297bdSopenharmony_ci if (!data.ReadString(mode)) { 2643fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read mode failed", __func__); 2653fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2663fc297bdSopenharmony_ci } 2673fc297bdSopenharmony_ci if (mode.length() > MSG_STRING_MAX_LEN) { 2683fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2693fc297bdSopenharmony_ci } 2703fc297bdSopenharmony_ci 2713fc297bdSopenharmony_ci bool status; 2723fc297bdSopenharmony_ci if (!data.ReadBool(status)) { 2733fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerfStub::%{public}s read status failed", __func__); 2743fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2753fc297bdSopenharmony_ci } 2763fc297bdSopenharmony_ci 2773fc297bdSopenharmony_ci RequestDeviceMode(mode, status); 2783fc297bdSopenharmony_ci return ERR_OK; 2793fc297bdSopenharmony_ci} 2803fc297bdSopenharmony_ci 2813fc297bdSopenharmony_ciint32_t SocPerfStub::StubRequestCmdIdCount(MessageParcel &data, MessageParcel &reply) 2823fc297bdSopenharmony_ci{ 2833fc297bdSopenharmony_ci int32_t callingUid = IPCSkeleton::GetCallingUid(); 2843fc297bdSopenharmony_ci std::string msg; 2853fc297bdSopenharmony_ci if ((ENG_MODE == 0 && callingUid != HIVIEW_UID) || !data.ReadString(msg)) { 2863fc297bdSopenharmony_ci SOC_PERF_LOGE("not have right to do RequestCmdIdCount"); 2873fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2883fc297bdSopenharmony_ci } 2893fc297bdSopenharmony_ci if (!reply.WriteString(RequestCmdIdCount(msg))) { 2903fc297bdSopenharmony_ci SOC_PERF_LOGE("write RequestCmdIdCount ret failed"); 2913fc297bdSopenharmony_ci return ERR_INVALID_STATE; 2923fc297bdSopenharmony_ci } 2933fc297bdSopenharmony_ci return ERR_OK; 2943fc297bdSopenharmony_ci} 2953fc297bdSopenharmony_ci 2963fc297bdSopenharmony_ciconst std::string NEEDED_PERMISSION = "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT"; 2973fc297bdSopenharmony_ci 2983fc297bdSopenharmony_cibool SocPerfStub::HasPerfPermission() 2993fc297bdSopenharmony_ci{ 3003fc297bdSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 3013fc297bdSopenharmony_ci auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(accessToken); 3023fc297bdSopenharmony_ci if (int(tokenType) == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) { 3033fc297bdSopenharmony_ci uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID(); 3043fc297bdSopenharmony_ci if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) { 3053fc297bdSopenharmony_ci SOC_PERF_LOGE("Invalid Permission to SocPerf"); 3063fc297bdSopenharmony_ci return false; 3073fc297bdSopenharmony_ci } 3083fc297bdSopenharmony_ci } 3093fc297bdSopenharmony_ci int32_t hasPermission = Security::AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, NEEDED_PERMISSION); 3103fc297bdSopenharmony_ci if (hasPermission != 0) { 3113fc297bdSopenharmony_ci SOC_PERF_LOGE("SocPerf: not have Permission"); 3123fc297bdSopenharmony_ci return false; 3133fc297bdSopenharmony_ci } 3143fc297bdSopenharmony_ci return true; 3153fc297bdSopenharmony_ci} 3163fc297bdSopenharmony_ci} // namespace SOCPERF 3173fc297bdSopenharmony_ci} // namespace OHOS 318