13c3173acSopenharmony_ci/*
23c3173acSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
33c3173acSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43c3173acSopenharmony_ci * you may not use this file except in compliance with the License.
53c3173acSopenharmony_ci * You may obtain a copy of the License at
63c3173acSopenharmony_ci *
73c3173acSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83c3173acSopenharmony_ci *
93c3173acSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103c3173acSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113c3173acSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123c3173acSopenharmony_ci * See the License for the specific language governing permissions and
133c3173acSopenharmony_ci * limitations under the License.
143c3173acSopenharmony_ci */
153c3173acSopenharmony_ci
163c3173acSopenharmony_ci#include "concurrent_task_service_stub.h"
173c3173acSopenharmony_ci#include "concurrent_task_log.h"
183c3173acSopenharmony_ci#include "concurrent_task_errors.h"
193c3173acSopenharmony_ci#include "string_ex.h"
203c3173acSopenharmony_ci#include "ipc_skeleton.h"
213c3173acSopenharmony_ci
223c3173acSopenharmony_cinamespace OHOS {
233c3173acSopenharmony_cinamespace ConcurrentTask {
243c3173acSopenharmony_cinamespace {
253c3173acSopenharmony_ci    bool IsValidToken(MessageParcel& data)
263c3173acSopenharmony_ci    {
273c3173acSopenharmony_ci        std::u16string descriptor = ConcurrentTaskServiceStub::GetDescriptor();
283c3173acSopenharmony_ci        std::u16string remoteDescriptor = data.ReadInterfaceToken();
293c3173acSopenharmony_ci        return descriptor == remoteDescriptor;
303c3173acSopenharmony_ci    }
313c3173acSopenharmony_ci}
323c3173acSopenharmony_ci
333c3173acSopenharmony_ciConcurrentTaskServiceStub::ConcurrentTaskServiceStub()
343c3173acSopenharmony_ci{
353c3173acSopenharmony_ci    Init();
363c3173acSopenharmony_ci}
373c3173acSopenharmony_ci
383c3173acSopenharmony_ciConcurrentTaskServiceStub::~ConcurrentTaskServiceStub()
393c3173acSopenharmony_ci{
403c3173acSopenharmony_ci    funcMap_.clear();
413c3173acSopenharmony_ci}
423c3173acSopenharmony_ci
433c3173acSopenharmony_ciint32_t ConcurrentTaskServiceStub::ReportDataInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
443c3173acSopenharmony_ci{
453c3173acSopenharmony_ci    if (!IsValidToken(data)) {
463c3173acSopenharmony_ci        return ERR_CONCURRENT_TASK_PARCEL_ERROR;
473c3173acSopenharmony_ci    }
483c3173acSopenharmony_ci
493c3173acSopenharmony_ci    uint32_t type = 0;
503c3173acSopenharmony_ci    int64_t value = 0;
513c3173acSopenharmony_ci    std::string payload;
523c3173acSopenharmony_ci    if (!data.ReadUint32(type) || !data.ReadInt64(value) || !data.ReadString(payload)) {
533c3173acSopenharmony_ci        CONCUR_LOGE("Read info failed in ReportData Stub");
543c3173acSopenharmony_ci        return IPC_STUB_ERR;
553c3173acSopenharmony_ci    }
563c3173acSopenharmony_ci    if (payload.empty()) {
573c3173acSopenharmony_ci        return ERR_OK;
583c3173acSopenharmony_ci    }
593c3173acSopenharmony_ci    ReportData(type, value, StringToJson(payload));
603c3173acSopenharmony_ci    return ERR_OK;
613c3173acSopenharmony_ci}
623c3173acSopenharmony_ci
633c3173acSopenharmony_ciint32_t ConcurrentTaskServiceStub::QueryIntervalInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
643c3173acSopenharmony_ci{
653c3173acSopenharmony_ci    if (!IsValidToken(data)) {
663c3173acSopenharmony_ci        return ERR_CONCURRENT_TASK_PARCEL_ERROR;
673c3173acSopenharmony_ci    }
683c3173acSopenharmony_ci    int item;
693c3173acSopenharmony_ci    IntervalReply queryRs;
703c3173acSopenharmony_ci    queryRs.rtgId = -1;
713c3173acSopenharmony_ci    queryRs.tid = -1;
723c3173acSopenharmony_ci    queryRs.paramA = -1;
733c3173acSopenharmony_ci    queryRs.paramB = -1;
743c3173acSopenharmony_ci    if (!data.ReadInt32(item) || !data.ReadInt32(queryRs.tid)) {
753c3173acSopenharmony_ci        CONCUR_LOGE("Read info failed in QueryInterval Stub");
763c3173acSopenharmony_ci        return IPC_STUB_ERR;
773c3173acSopenharmony_ci    }
783c3173acSopenharmony_ci    QueryInterval(item, queryRs);
793c3173acSopenharmony_ci    if (!reply.WriteInt32(queryRs.rtgId) || !reply.WriteInt32(queryRs.tid)
803c3173acSopenharmony_ci        || !reply.WriteInt32(queryRs.paramA) || !reply.WriteInt32(queryRs.paramB)
813c3173acSopenharmony_ci        || !reply.WriteString(queryRs.bundleName)) {
823c3173acSopenharmony_ci        CONCUR_LOGE("Write info failed in QueryInterval Stub");
833c3173acSopenharmony_ci        return IPC_STUB_ERR;
843c3173acSopenharmony_ci    }
853c3173acSopenharmony_ci    return ERR_OK;
863c3173acSopenharmony_ci}
873c3173acSopenharmony_ci
883c3173acSopenharmony_ciint32_t ConcurrentTaskServiceStub::QueryDeadlineInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
893c3173acSopenharmony_ci{
903c3173acSopenharmony_ci    if (!IsValidToken(data)) {
913c3173acSopenharmony_ci        return ERR_CONCURRENT_TASK_PARCEL_ERROR;
923c3173acSopenharmony_ci    }
933c3173acSopenharmony_ci    int queryItem;
943c3173acSopenharmony_ci    DeadlineReply ddlReply;
953c3173acSopenharmony_ci    std::string payload;
963c3173acSopenharmony_ci    if (!data.ReadInt32(queryItem) || !data.ReadString(payload)) {
973c3173acSopenharmony_ci        CONCUR_LOGE("Read info failed in QueryDeadline Stub");
983c3173acSopenharmony_ci        return IPC_STUB_ERR;
993c3173acSopenharmony_ci    }
1003c3173acSopenharmony_ci    if (payload.empty()) {
1013c3173acSopenharmony_ci        return ERR_OK;
1023c3173acSopenharmony_ci    }
1033c3173acSopenharmony_ci    QueryDeadline(queryItem, ddlReply, StringToJson(payload));
1043c3173acSopenharmony_ci    return ERR_OK;
1053c3173acSopenharmony_ci}
1063c3173acSopenharmony_ci
1073c3173acSopenharmony_ciint32_t ConcurrentTaskServiceStub::RequestAuthInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
1083c3173acSopenharmony_ci{
1093c3173acSopenharmony_ci    if (!IsValidToken(data)) {
1103c3173acSopenharmony_ci        return ERR_CONCURRENT_TASK_PARCEL_ERROR;
1113c3173acSopenharmony_ci    }
1123c3173acSopenharmony_ci
1133c3173acSopenharmony_ci    std::string payload;
1143c3173acSopenharmony_ci    if (!data.ReadString(payload)) {
1153c3173acSopenharmony_ci        CONCUR_LOGE("Read info failed in RequestAuth Stub");
1163c3173acSopenharmony_ci        return IPC_STUB_ERR;
1173c3173acSopenharmony_ci    }
1183c3173acSopenharmony_ci    if (payload.empty()) {
1193c3173acSopenharmony_ci        return ERR_OK;
1203c3173acSopenharmony_ci    }
1213c3173acSopenharmony_ci    RequestAuth(StringToJson(payload));
1223c3173acSopenharmony_ci    return ERR_OK;
1233c3173acSopenharmony_ci}
1243c3173acSopenharmony_ci
1253c3173acSopenharmony_ciint32_t ConcurrentTaskServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
1263c3173acSopenharmony_ci    MessageParcel& reply, MessageOption& option)
1273c3173acSopenharmony_ci{
1283c3173acSopenharmony_ci    auto uid = IPCSkeleton::GetCallingUid();
1293c3173acSopenharmony_ci    auto pid = IPCSkeleton::GetCallingPid();
1303c3173acSopenharmony_ci    CONCUR_LOGD("ConcurrentTaskServiceStub::OnRemoteRequest, code = %{public}u, flags = %{public}d,"
1313c3173acSopenharmony_ci        " uid = %{public}d pid = %{public}d", code, option.GetFlags(), uid, pid);
1323c3173acSopenharmony_ci
1333c3173acSopenharmony_ci    auto itFunc = funcMap_.find(code);
1343c3173acSopenharmony_ci    if (itFunc != funcMap_.end()) {
1353c3173acSopenharmony_ci        auto requestFunc = itFunc->second;
1363c3173acSopenharmony_ci        if (requestFunc) {
1373c3173acSopenharmony_ci            return requestFunc(data, reply);
1383c3173acSopenharmony_ci        }
1393c3173acSopenharmony_ci    }
1403c3173acSopenharmony_ci    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
1413c3173acSopenharmony_ci}
1423c3173acSopenharmony_ci
1433c3173acSopenharmony_ciJson::Value ConcurrentTaskServiceStub::StringToJson(const std::string& payload)
1443c3173acSopenharmony_ci{
1453c3173acSopenharmony_ci    bool res;
1463c3173acSopenharmony_ci    Json::CharReaderBuilder readerBuilder;
1473c3173acSopenharmony_ci    JSONCPP_STRING errs;
1483c3173acSopenharmony_ci    std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
1493c3173acSopenharmony_ci    Json::Value root;
1503c3173acSopenharmony_ci    if (!IsAsciiString(payload)) {
1513c3173acSopenharmony_ci        CONCUR_LOGE("Payload is not ascii string");
1523c3173acSopenharmony_ci        return root;
1533c3173acSopenharmony_ci    }
1543c3173acSopenharmony_ci    try {
1553c3173acSopenharmony_ci        res = jsonReader->parse(payload.c_str(), payload.c_str() + payload.length(), &root, &errs);
1563c3173acSopenharmony_ci    } catch (...) {
1573c3173acSopenharmony_ci        CONCUR_LOGE("Unexpected json parse");
1583c3173acSopenharmony_ci        return root;
1593c3173acSopenharmony_ci    }
1603c3173acSopenharmony_ci    if (!res || !errs.empty()) {
1613c3173acSopenharmony_ci        CONCUR_LOGE("ConcurentTaskServiceStub::payload = %{public}s Incorrect JSON format ", payload.c_str());
1623c3173acSopenharmony_ci    }
1633c3173acSopenharmony_ci    return root;
1643c3173acSopenharmony_ci}
1653c3173acSopenharmony_ci
1663c3173acSopenharmony_civoid ConcurrentTaskServiceStub::Init()
1673c3173acSopenharmony_ci{
1683c3173acSopenharmony_ci    funcMap_ = {
1693c3173acSopenharmony_ci        { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::REPORT_DATA),
1703c3173acSopenharmony_ci            [this](auto& data, auto& reply) {return ReportDataInner(data, reply); } },
1713c3173acSopenharmony_ci        { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::QUERY_INTERVAL),
1723c3173acSopenharmony_ci            [this](auto& data, auto& reply) {return QueryIntervalInner(data, reply); } },
1733c3173acSopenharmony_ci        { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::QUERY_DEADLINE),
1743c3173acSopenharmony_ci            [this](auto& data, auto& reply) {return QueryDeadlineInner(data, reply); } },
1753c3173acSopenharmony_ci        { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::REQUEST_AUTH),
1763c3173acSopenharmony_ci            [this](auto& data, auto& reply) {return RequestAuthInner(data, reply); } },
1773c3173acSopenharmony_ci    };
1783c3173acSopenharmony_ci}
1793c3173acSopenharmony_ci} // namespace ResourceSchedule
1803c3173acSopenharmony_ci} // namespace OHOS
181