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