1 /*
2 * Copyright (c) 2024 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 "socperf_stub.h"
17 #include "accesstoken_kit.h"
18 #include "ipc_skeleton.h"
19 #include "parameters.h"
20 #include "socperf_ipc_interface_code.h"
21 #include "socperf_log.h"
22 #include "tokenid_kit.h"
23
24 namespace OHOS {
25 namespace SOCPERF {
26 namespace {
27 constexpr int32_t HIVIEW_UID = 1201;
28 constexpr int32_t MSG_STRING_MAX_LEN = 1024;
29 constexpr int32_t MSG_VECTOR_MAX_LEN = 1024;
30 constexpr int32_t MSG_VECTOR_INVALID_LEN = 0;
31 const int32_t ENG_MODE = OHOS::system::GetIntParameter("const.debuggable", 0);
32 }
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)33 int32_t SocPerfStub::OnRemoteRequest(uint32_t code, MessageParcel &data,
34 MessageParcel &reply, MessageOption &option)
35 {
36 auto remoteDescriptor = data.ReadInterfaceToken();
37 if (GetDescriptor() != remoteDescriptor || !HasPerfPermission()) {
38 return ERR_INVALID_STATE;
39 }
40
41 int32_t ret = ERR_OK;
42 switch (code) {
43 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_PERF_REQUEST): {
44 ret = StubPerfRequest(data);
45 break;
46 }
47 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_PERF_REQUEST_EX): {
48 ret = StubPerfRequestEx(data);
49 break;
50 }
51 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_POWER_LIMIT_BOOST_FREQ): {
52 ret = StubPowerLimitBoost(data);
53 break;
54 }
55 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_THERMAL_LIMIT_BOOST_FREQ): {
56 ret = StubThermalLimitBoost(data);
57 break;
58 }
59 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_LIMIT_REQUEST): {
60 ret = StubLimitRequest(data);
61 break;
62 }
63 default:
64 return OnRemoteRequestExt(code, data, reply, option);
65 }
66 return ret;
67 }
68
OnRemoteRequestExt(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)69 int32_t SocPerfStub::OnRemoteRequestExt(uint32_t code, MessageParcel &data,
70 MessageParcel &reply, MessageOption &option)
71 {
72 int32_t ret = ERR_OK;
73 switch (code) {
74 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_SET_STATUS): {
75 ret = StubSetRequestStatus(data);
76 break;
77 }
78 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_SET_THERMAL_LEVEL): {
79 ret = StubSetThermalLevel(data);
80 break;
81 }
82 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_SET_DEVICE_MODE): {
83 ret = StubRequestDeviceMode(data);
84 break;
85 }
86 case static_cast<uint32_t>(SocPerfInterfaceCode::TRANS_IPC_ID_REQUEST_CMDID_COUNT): {
87 ret = StubRequestCmdIdCount(data, reply);
88 break;
89 }
90 default:
91 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
92 }
93 return ret;
94 }
95
StubPerfRequest(MessageParcel & data)96 int32_t SocPerfStub::StubPerfRequest(MessageParcel &data)
97 {
98 int32_t cmdId = 0;
99 if (!data.ReadInt32(cmdId)) {
100 SOC_PERF_LOGE("SocPerfStub::%{public}s read cmdId failed", __func__);
101 return ERR_INVALID_STATE;
102 }
103
104 std::string msg;
105 if (!data.ReadString(msg)) {
106 SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__);
107 return ERR_INVALID_STATE;
108 }
109 if (msg.length() > MSG_STRING_MAX_LEN) {
110 return ERR_INVALID_STATE;
111 }
112
113 PerfRequest(cmdId, msg);
114 return ERR_OK;
115 }
116
StubPerfRequestEx(MessageParcel & data)117 int32_t SocPerfStub::StubPerfRequestEx(MessageParcel &data)
118 {
119 int32_t cmdId = 0;
120 if (!data.ReadInt32(cmdId)) {
121 SOC_PERF_LOGE("SocPerfStub::%{public}s read cmdId failed", __func__);
122 return ERR_INVALID_STATE;
123 }
124
125 bool onOffTag = false;
126 if (!data.ReadBool(onOffTag)) {
127 SOC_PERF_LOGE("SocPerfStub::%{public}s read onOffTag failed", __func__);
128 return ERR_INVALID_STATE;
129 }
130
131 std::string msg;
132 if (!data.ReadString(msg)) {
133 SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__);
134 return ERR_INVALID_STATE;
135 }
136 if (msg.length() > MSG_STRING_MAX_LEN) {
137 return ERR_INVALID_STATE;
138 }
139
140 PerfRequestEx(cmdId, onOffTag, msg);
141 return ERR_OK;
142 }
143
StubPowerLimitBoost(MessageParcel & data)144 int32_t SocPerfStub::StubPowerLimitBoost(MessageParcel &data)
145 {
146 bool onOffTag = false;
147 if (!data.ReadBool(onOffTag)) {
148 SOC_PERF_LOGE("SocPerfStub::%{public}s read onOffTag failed", __func__);
149 return ERR_INVALID_STATE;
150 }
151
152 std::string msg;
153 if (!data.ReadString(msg)) {
154 SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__);
155 return ERR_INVALID_STATE;
156 }
157 if (msg.length() > MSG_STRING_MAX_LEN) {
158 return ERR_INVALID_STATE;
159 }
160
161 PowerLimitBoost(onOffTag, msg);
162 return ERR_OK;
163 }
164
StubThermalLimitBoost(MessageParcel & data)165 int32_t SocPerfStub::StubThermalLimitBoost(MessageParcel &data)
166 {
167 bool onOffTag = false;
168 if (!data.ReadBool(onOffTag)) {
169 SOC_PERF_LOGE("SocPerfStub::%{public}s read onOffTag failed", __func__);
170 return ERR_INVALID_STATE;
171 }
172
173 std::string msg;
174 if (!data.ReadString(msg)) {
175 SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__);
176 return ERR_INVALID_STATE;
177 }
178 if (msg.length() > MSG_STRING_MAX_LEN) {
179 return ERR_INVALID_STATE;
180 }
181
182 ThermalLimitBoost(onOffTag, msg);
183 return ERR_OK;
184 }
185
StubLimitRequest(MessageParcel & data)186 int32_t SocPerfStub::StubLimitRequest(MessageParcel &data)
187 {
188 int32_t clientId;
189 if (!data.ReadInt32(clientId)) {
190 SOC_PERF_LOGE("SocPerfStub::%{public}s read clientId failed", __func__);
191 return ERR_INVALID_STATE;
192 }
193
194 std::vector<int32_t> tags;
195 if (!data.ReadInt32Vector(&tags)) {
196 SOC_PERF_LOGE("error tags to do StubLimitRequest");
197 return ERR_INVALID_STATE;
198 }
199 if (tags.size() == MSG_VECTOR_INVALID_LEN || tags.size() > MSG_VECTOR_MAX_LEN) {
200 SOC_PERF_LOGE("error tags to do StubLimitRequest");
201 return ERR_INVALID_STATE;
202 }
203
204 std::vector<int64_t> configs;
205 if (!data.ReadInt64Vector(&configs)) {
206 SOC_PERF_LOGE("error configs to do StubLimitRequest");
207 return ERR_INVALID_STATE;
208 }
209 if (configs.size() == MSG_VECTOR_INVALID_LEN || configs.size() > MSG_VECTOR_MAX_LEN) {
210 SOC_PERF_LOGE("error configs to do StubLimitRequest");
211 return ERR_INVALID_STATE;
212 }
213
214 std::string msg;
215 if (!data.ReadString(msg)) {
216 SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__);
217 return ERR_INVALID_STATE;
218 }
219 if (msg.length() > MSG_STRING_MAX_LEN) {
220 return ERR_INVALID_STATE;
221 }
222
223 LimitRequest(clientId, tags, configs, msg);
224 return ERR_OK;
225 }
226
StubSetRequestStatus(MessageParcel & data)227 int32_t SocPerfStub::StubSetRequestStatus(MessageParcel &data)
228 {
229 bool requestEnable;
230 if (!data.ReadBool(requestEnable)) {
231 SOC_PERF_LOGE("SocPerfStub::%{public}s read requestEnable failed", __func__);
232 return ERR_INVALID_STATE;
233 }
234
235 std::string msg;
236 if (!data.ReadString(msg)) {
237 SOC_PERF_LOGE("SocPerfStub::%{public}s read msg failed", __func__);
238 return ERR_INVALID_STATE;
239 }
240 if (msg.length() > MSG_STRING_MAX_LEN) {
241 return ERR_INVALID_STATE;
242 }
243
244 SetRequestStatus(requestEnable, msg);
245 return ERR_OK;
246 }
247
StubSetThermalLevel(MessageParcel & data)248 int32_t SocPerfStub::StubSetThermalLevel(MessageParcel &data)
249 {
250 int32_t levelId;
251 if (!data.ReadInt32(levelId)) {
252 SOC_PERF_LOGE("SocPerfStub::%{public}s read levelId failed", __func__);
253 return ERR_INVALID_STATE;
254 }
255
256 SetThermalLevel(levelId);
257 return ERR_OK;
258 }
259
StubRequestDeviceMode(MessageParcel & data)260 int32_t SocPerfStub::StubRequestDeviceMode(MessageParcel &data)
261 {
262 std::string mode;
263 if (!data.ReadString(mode)) {
264 SOC_PERF_LOGE("SocPerfStub::%{public}s read mode failed", __func__);
265 return ERR_INVALID_STATE;
266 }
267 if (mode.length() > MSG_STRING_MAX_LEN) {
268 return ERR_INVALID_STATE;
269 }
270
271 bool status;
272 if (!data.ReadBool(status)) {
273 SOC_PERF_LOGE("SocPerfStub::%{public}s read status failed", __func__);
274 return ERR_INVALID_STATE;
275 }
276
277 RequestDeviceMode(mode, status);
278 return ERR_OK;
279 }
280
StubRequestCmdIdCount(MessageParcel & data,MessageParcel & reply)281 int32_t SocPerfStub::StubRequestCmdIdCount(MessageParcel &data, MessageParcel &reply)
282 {
283 int32_t callingUid = IPCSkeleton::GetCallingUid();
284 std::string msg;
285 if ((ENG_MODE == 0 && callingUid != HIVIEW_UID) || !data.ReadString(msg)) {
286 SOC_PERF_LOGE("not have right to do RequestCmdIdCount");
287 return ERR_INVALID_STATE;
288 }
289 if (!reply.WriteString(RequestCmdIdCount(msg))) {
290 SOC_PERF_LOGE("write RequestCmdIdCount ret failed");
291 return ERR_INVALID_STATE;
292 }
293 return ERR_OK;
294 }
295
296 const std::string NEEDED_PERMISSION = "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT";
297
HasPerfPermission()298 bool SocPerfStub::HasPerfPermission()
299 {
300 uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
301 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(accessToken);
302 if (int(tokenType) == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
303 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
304 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
305 SOC_PERF_LOGE("Invalid Permission to SocPerf");
306 return false;
307 }
308 }
309 int32_t hasPermission = Security::AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, NEEDED_PERMISSION);
310 if (hasPermission != 0) {
311 SOC_PERF_LOGE("SocPerf: not have Permission");
312 return false;
313 }
314 return true;
315 }
316 } // namespace SOCPERF
317 } // namespace OHOS
318