1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "concurrent_task_service_stub.h"
17 #include "concurrent_task_log.h"
18 #include "concurrent_task_errors.h"
19 #include "string_ex.h"
20 #include "ipc_skeleton.h"
21 
22 namespace OHOS {
23 namespace ConcurrentTask {
24 namespace {
IsValidToken(MessageParcel & data)25     bool IsValidToken(MessageParcel& data)
26     {
27         std::u16string descriptor = ConcurrentTaskServiceStub::GetDescriptor();
28         std::u16string remoteDescriptor = data.ReadInterfaceToken();
29         return descriptor == remoteDescriptor;
30     }
31 }
32 
ConcurrentTaskServiceStub()33 ConcurrentTaskServiceStub::ConcurrentTaskServiceStub()
34 {
35     Init();
36 }
37 
~ConcurrentTaskServiceStub()38 ConcurrentTaskServiceStub::~ConcurrentTaskServiceStub()
39 {
40     funcMap_.clear();
41 }
42 
43 int32_t ConcurrentTaskServiceStub::ReportDataInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
44 {
45     if (!IsValidToken(data)) {
46         return ERR_CONCURRENT_TASK_PARCEL_ERROR;
47     }
48 
49     uint32_t type = 0;
50     int64_t value = 0;
51     std::string payload;
52     if (!data.ReadUint32(type) || !data.ReadInt64(value) || !data.ReadString(payload)) {
53         CONCUR_LOGE("Read info failed in ReportData Stub");
54         return IPC_STUB_ERR;
55     }
56     if (payload.empty()) {
57         return ERR_OK;
58     }
59     ReportData(type, value, StringToJson(payload));
60     return ERR_OK;
61 }
62 
63 int32_t ConcurrentTaskServiceStub::QueryIntervalInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
64 {
65     if (!IsValidToken(data)) {
66         return ERR_CONCURRENT_TASK_PARCEL_ERROR;
67     }
68     int item;
69     IntervalReply queryRs;
70     queryRs.rtgId = -1;
71     queryRs.tid = -1;
72     queryRs.paramA = -1;
73     queryRs.paramB = -1;
74     if (!data.ReadInt32(item) || !data.ReadInt32(queryRs.tid)) {
75         CONCUR_LOGE("Read info failed in QueryInterval Stub");
76         return IPC_STUB_ERR;
77     }
78     QueryInterval(item, queryRs);
79     if (!reply.WriteInt32(queryRs.rtgId) || !reply.WriteInt32(queryRs.tid)
80         || !reply.WriteInt32(queryRs.paramA) || !reply.WriteInt32(queryRs.paramB)
81         || !reply.WriteString(queryRs.bundleName)) {
82         CONCUR_LOGE("Write info failed in QueryInterval Stub");
83         return IPC_STUB_ERR;
84     }
85     return ERR_OK;
86 }
87 
88 int32_t ConcurrentTaskServiceStub::QueryDeadlineInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
89 {
90     if (!IsValidToken(data)) {
91         return ERR_CONCURRENT_TASK_PARCEL_ERROR;
92     }
93     int queryItem;
94     DeadlineReply ddlReply;
95     std::string payload;
96     if (!data.ReadInt32(queryItem) || !data.ReadString(payload)) {
97         CONCUR_LOGE("Read info failed in QueryDeadline Stub");
98         return IPC_STUB_ERR;
99     }
100     if (payload.empty()) {
101         return ERR_OK;
102     }
103     QueryDeadline(queryItem, ddlReply, StringToJson(payload));
104     return ERR_OK;
105 }
106 
107 int32_t ConcurrentTaskServiceStub::RequestAuthInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply)
108 {
109     if (!IsValidToken(data)) {
110         return ERR_CONCURRENT_TASK_PARCEL_ERROR;
111     }
112 
113     std::string payload;
114     if (!data.ReadString(payload)) {
115         CONCUR_LOGE("Read info failed in RequestAuth Stub");
116         return IPC_STUB_ERR;
117     }
118     if (payload.empty()) {
119         return ERR_OK;
120     }
121     RequestAuth(StringToJson(payload));
122     return ERR_OK;
123 }
124 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)125 int32_t ConcurrentTaskServiceStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
126     MessageParcel& reply, MessageOption& option)
127 {
128     auto uid = IPCSkeleton::GetCallingUid();
129     auto pid = IPCSkeleton::GetCallingPid();
130     CONCUR_LOGD("ConcurrentTaskServiceStub::OnRemoteRequest, code = %{public}u, flags = %{public}d,"
131         " uid = %{public}d pid = %{public}d", code, option.GetFlags(), uid, pid);
132 
133     auto itFunc = funcMap_.find(code);
134     if (itFunc != funcMap_.end()) {
135         auto requestFunc = itFunc->second;
136         if (requestFunc) {
137             return requestFunc(data, reply);
138         }
139     }
140     return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
141 }
142 
StringToJson(const std::string & payload)143 Json::Value ConcurrentTaskServiceStub::StringToJson(const std::string& payload)
144 {
145     bool res;
146     Json::CharReaderBuilder readerBuilder;
147     JSONCPP_STRING errs;
148     std::unique_ptr<Json::CharReader> const jsonReader(readerBuilder.newCharReader());
149     Json::Value root;
150     if (!IsAsciiString(payload)) {
151         CONCUR_LOGE("Payload is not ascii string");
152         return root;
153     }
154     try {
155         res = jsonReader->parse(payload.c_str(), payload.c_str() + payload.length(), &root, &errs);
156     } catch (...) {
157         CONCUR_LOGE("Unexpected json parse");
158         return root;
159     }
160     if (!res || !errs.empty()) {
161         CONCUR_LOGE("ConcurentTaskServiceStub::payload = %{public}s Incorrect JSON format ", payload.c_str());
162     }
163     return root;
164 }
165 
Init()166 void ConcurrentTaskServiceStub::Init()
167 {
168     funcMap_ = {
169         { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::REPORT_DATA),
170             [this](auto& data, auto& reply) {return ReportDataInner(data, reply); } },
171         { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::QUERY_INTERVAL),
172             [this](auto& data, auto& reply) {return QueryIntervalInner(data, reply); } },
173         { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::QUERY_DEADLINE),
174             [this](auto& data, auto& reply) {return QueryDeadlineInner(data, reply); } },
175         { static_cast<uint32_t>(ConcurrentTaskInterfaceCode::REQUEST_AUTH),
176             [this](auto& data, auto& reply) {return RequestAuthInner(data, reply); } },
177     };
178 }
179 } // namespace ResourceSchedule
180 } // namespace OHOS
181