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 #include "work_sched_service_stub.h"
16
17 #include <message_parcel.h>
18 #include <string_ex.h>
19
20 #include "work_sched_common.h"
21 #include "work_sched_errors.h"
22
23 #ifdef HICOLLIE_ENABLE
24 #include "xcollie/xcollie.h"
25 #include "xcollie/xcollie_define.h"
26 #define XCOLLIE_TIMEOUT_SECONDS 10
27 #endif
28
29 namespace OHOS {
30 namespace WorkScheduler {
HandleObtainAllWorksRequest(MessageParcel & data,MessageParcel & reply)31 int32_t WorkSchedServiceStub::HandleObtainAllWorksRequest(MessageParcel &data, MessageParcel &reply)
32 {
33 std::list<std::shared_ptr<WorkInfo>> workInfos;
34 int32_t ret = ObtainAllWorksStub(data, workInfos);
35 uint32_t worksize = workInfos.size();
36 reply.WriteInt32(ret);
37 reply.WriteInt32(worksize);
38 for (auto workInfo : workInfos) {
39 reply.WriteParcelable(&*workInfo);
40 }
41 return ERR_OK;
42 }
43
HandleGetWorkStatusRequest(MessageParcel & data,MessageParcel & reply)44 int32_t WorkSchedServiceStub::HandleGetWorkStatusRequest(MessageParcel &data, MessageParcel &reply)
45 {
46 WS_HILOGI("call GetWorkStatus");
47 std::shared_ptr<WorkInfo> workInfo;
48 int32_t ret = GetWorkStatusStub(data, workInfo);
49 reply.WriteInt32(ret);
50 reply.WriteParcelable(&*workInfo);
51 return ERR_OK;
52 }
53
HandleGetAllRunningWorksRequest(MessageParcel & reply)54 int32_t WorkSchedServiceStub::HandleGetAllRunningWorksRequest(MessageParcel &reply)
55 {
56 std::list<std::shared_ptr<WorkInfo>> workInfos;
57 int32_t ret = GetAllRunningWorksStub(workInfos);
58 uint32_t worksize = workInfos.size();
59 reply.WriteInt32(ret);
60 reply.WriteInt32(worksize);
61 for (auto workInfo : workInfos) {
62 reply.WriteParcelable(&*workInfo);
63 }
64 return ERR_OK;
65 }
66
HandleIsLastWorkTimeOutRequest(MessageParcel & data,MessageParcel & reply)67 int32_t WorkSchedServiceStub::HandleIsLastWorkTimeOutRequest(MessageParcel &data, MessageParcel &reply)
68 {
69 bool isLastWorkTimeout;
70 int32_t ret = IsLastWorkTimeoutStub(data, isLastWorkTimeout);
71 if (!reply.WriteInt32(ret)) {
72 WS_HILOGE("Handle IsLastWorkTimeOut request failed, write result error");
73 return E_PARCEL_OPERATION_FAILED;
74 }
75
76 if (!reply.WriteBool(isLastWorkTimeout)) {
77 WS_HILOGE("Handle IsLastWorkTimeOut request failed, write result error");
78 return E_PARCEL_OPERATION_FAILED;
79 }
80 return ret;
81 }
82
HandleSetWorkSchedulerConfig(MessageParcel & data,MessageParcel & reply)83 int32_t WorkSchedServiceStub::HandleSetWorkSchedulerConfig(MessageParcel &data, MessageParcel &reply)
84 {
85 std::string configData;
86 if (!data.ReadString(configData)) {
87 WS_HILOGE("HandleSetWorkSchedulerConfig read parce configData error");
88 return E_PARCEL_OPERATION_FAILED;
89 }
90 int32_t sourceType;
91 if (!data.ReadInt32(sourceType)) {
92 WS_HILOGE("HandleSetWorkSchedulerConfig read parce sourceType error");
93 return E_PARCEL_OPERATION_FAILED;
94 }
95 int32_t ret = SetWorkSchedulerConfig(configData, sourceType);
96 if (!reply.WriteInt32(ret)) {
97 WS_HILOGE("HandleSetWorkSchedulerConfig write result failed, Errcode=%{public}d", ret);
98 return E_PARCEL_OPERATION_FAILED;
99 }
100 return ret;
101 }
102
HandleRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)103 int32_t WorkSchedServiceStub::HandleRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
104 MessageOption &option)
105 {
106 switch (code) {
107 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::START_WORK): {
108 int32_t ret = StartWorkStub(data);
109 reply.WriteInt32(ret);
110 return ret;
111 }
112 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::STOP_WORK): {
113 int32_t ret = StopWorkStub(data);
114 reply.WriteInt32(ret);
115 return ret;
116 }
117 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::STOP_AND_CANCEL_WORK): {
118 int32_t ret = StopAndCancelWorkStub(data);
119 reply.WriteInt32(ret);
120 return ret;
121 }
122 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::STOP_AND_CLEAR_WORKS): {
123 int32_t ret = StopAndClearWorksStub(data);
124 reply.WriteInt32(ret);
125 return ret;
126 }
127 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::IS_LAST_WORK_TIMEOUT): {
128 return HandleIsLastWorkTimeOutRequest(data, reply);
129 }
130 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::OBTAIN_ALL_WORKS): {
131 return HandleObtainAllWorksRequest(data, reply);
132 }
133 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::GET_WORK_STATUS): {
134 return HandleGetWorkStatusRequest(data, reply);
135 }
136 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::GET_ALL_RUNNING_WORKS): {
137 return HandleGetAllRunningWorksRequest(reply);
138 }
139 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::PAUSE_RUNNING_WORKS): {
140 return PauseRunningWorksStub(data, reply);
141 }
142 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::RESUME_PAUSED_WORKS): {
143 return ResumePausedWorksStub(data, reply);
144 }
145 case static_cast<int32_t>(IWorkSchedServiceInterfaceCode::SET_WORK_SCHEDULER_CONFIG): {
146 return HandleSetWorkSchedulerConfig(data, reply);
147 }
148 default: {
149 WS_HILOGD("OnRemoteRequest switch default, code: %{public}u", code);
150 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
151 }
152 }
153 return ERR_OK;
154 }
155
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)156 int32_t WorkSchedServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
157 MessageOption &option)
158 {
159 WS_HILOGD("cmd = %{public}u, flags = %{public}d", code, option.GetFlags());
160 std::u16string descriptor = WorkSchedServiceStub::GetDescriptor();
161 std::u16string remoteDescriptor = data.ReadInterfaceToken();
162 if (descriptor != remoteDescriptor) {
163 WS_HILOGE("failed, descriptor is not matched!");
164 return E_PARCEL_OPERATION_FAILED;
165 }
166 int32_t idTimer = SetTimer(code);
167 int32_t result = HandleRequest(code, data, reply, option);
168 CancelTimer(idTimer);
169 return result;
170 }
171
StartWorkStub(MessageParcel & data)172 int32_t WorkSchedServiceStub::StartWorkStub(MessageParcel& data)
173 {
174 sptr<WorkInfo> workInfo = data.ReadStrongParcelable<WorkInfo>();
175 if (workInfo == nullptr) {
176 WS_HILOGD("workInfo is nullptr");
177 return E_PARCEL_OPERATION_FAILED;
178 }
179 return StartWork(*workInfo);
180 }
181
StopWorkStub(MessageParcel & data)182 int32_t WorkSchedServiceStub::StopWorkStub(MessageParcel& data)
183 {
184 sptr<WorkInfo> workInfo = data.ReadStrongParcelable<WorkInfo>();
185 if (workInfo == nullptr) {
186 WS_HILOGD("workInfo is nullptr");
187 return E_PARCEL_OPERATION_FAILED;
188 }
189 return StopWork(*workInfo);
190 }
191
StopAndCancelWorkStub(MessageParcel & data)192 int32_t WorkSchedServiceStub::StopAndCancelWorkStub(MessageParcel& data)
193 {
194 sptr<WorkInfo> workInfo = data.ReadStrongParcelable<WorkInfo>();
195 if (workInfo == nullptr) {
196 WS_HILOGD("workInfo is nullptr");
197 return E_PARCEL_OPERATION_FAILED;
198 }
199 return StopAndCancelWork(*workInfo);
200 }
201
StopAndClearWorksStub(MessageParcel & data)202 int32_t WorkSchedServiceStub::StopAndClearWorksStub(MessageParcel& data)
203 {
204 return StopAndClearWorks();
205 }
206
IsLastWorkTimeoutStub(MessageParcel & data,bool & result)207 int32_t WorkSchedServiceStub::IsLastWorkTimeoutStub(MessageParcel& data, bool &result)
208 {
209 int32_t workId = data.ReadInt32();
210 return IsLastWorkTimeout(workId, result);
211 }
212
ObtainAllWorksStub(MessageParcel & data,std::list<std::shared_ptr<WorkInfo>> & workInfos)213 int32_t WorkSchedServiceStub::ObtainAllWorksStub(MessageParcel& data, std::list<std::shared_ptr<WorkInfo>>& workInfos)
214 {
215 return ObtainAllWorks(workInfos);
216 }
217
GetWorkStatusStub(MessageParcel & data,std::shared_ptr<WorkInfo> & workInfo)218 int32_t WorkSchedServiceStub::GetWorkStatusStub(MessageParcel& data, std::shared_ptr<WorkInfo>& workInfo)
219 {
220 int32_t workId;
221 READ_PARCEL_WITHOUT_RET(data, Int32, workId);
222 return GetWorkStatus(workId, workInfo);
223 }
224
GetAllRunningWorksStub(std::list<std::shared_ptr<WorkInfo>> & workInfos)225 int32_t WorkSchedServiceStub::GetAllRunningWorksStub(std::list<std::shared_ptr<WorkInfo>>& workInfos)
226 {
227 return GetAllRunningWorks(workInfos);
228 }
229
PauseRunningWorksStub(MessageParcel & data,MessageParcel & reply)230 int32_t WorkSchedServiceStub::PauseRunningWorksStub(MessageParcel& data, MessageParcel& reply)
231 {
232 int32_t uid = -1;
233 if (!data.ReadInt32(uid)) {
234 WS_HILOGE("PauseRunningWorksStub failed, read uid error");
235 return E_PARCEL_OPERATION_FAILED;
236 }
237 int32_t ret = PauseRunningWorks(uid);
238 if (!reply.WriteInt32(ret)) {
239 WS_HILOGE("PauseRunningWorksStub failed, write result error");
240 return E_PARCEL_OPERATION_FAILED;
241 }
242 return ret;
243 }
244
ResumePausedWorksStub(MessageParcel & data,MessageParcel & reply)245 int32_t WorkSchedServiceStub::ResumePausedWorksStub(MessageParcel& data, MessageParcel& reply)
246 {
247 int32_t uid = -1;
248 if (!data.ReadInt32(uid)) {
249 WS_HILOGE("ResumePausedWorksStub failed, read uid error");
250 return E_PARCEL_OPERATION_FAILED;
251 }
252 int32_t ret = ResumePausedWorks(uid);
253 if (!reply.WriteInt32(ret)) {
254 WS_HILOGE("ResumePausedWorksStub failed, write result error");
255 return E_PARCEL_OPERATION_FAILED;
256 }
257 return ret;
258 }
259
SetTimer(uint32_t code)260 int32_t WorkSchedServiceStub::SetTimer(uint32_t code)
261 {
262 #ifdef HICOLLIE_ENABLE
263 int32_t idTimer = HiviewDFX::INVALID_ID;
264 std::map<uint32_t, std::string>::iterator itCollieId = collieCodeStringMap_.find(code);
265 if (itCollieId != collieCodeStringMap_.end()) {
266 std::string collieStr = itCollieId->second;
267 std::string collieName = "WorkSchedulerServiceStub:" + collieStr;
268 unsigned int flag = HiviewDFX::XCOLLIE_FLAG_LOG | HiviewDFX::XCOLLIE_FLAG_RECOVERY;
269 auto TimerCallback = [collieStr](void *) {
270 WS_HILOGE("OnRemoteRequest timeout func: %{public}s", collieStr.c_str());
271 };
272 idTimer = HiviewDFX::XCollie::GetInstance().SetTimer(
273 collieName, XCOLLIE_TIMEOUT_SECONDS, TimerCallback, nullptr, flag);
274 WS_HILOGD("SetTimer id: %{public}d, name: %{public}s.", idTimer, collieName.c_str());
275 }
276 return idTimer;
277 #else
278 WS_HILOGD("No HICOLLIE_ENABLE");
279 return -1;
280 #endif
281 }
282
CancelTimer(int32_t id)283 void WorkSchedServiceStub::CancelTimer(int32_t id)
284 {
285 #ifdef HICOLLIE_ENABLE
286 if (id == HiviewDFX::INVALID_ID) {
287 return;
288 }
289 WS_HILOGD("CancelTimer id: %{public}d.", id);
290 HiviewDFX::XCollie::GetInstance().CancelTimer(id);
291 #else
292 return;
293 #endif
294 }
295 } // namespace WorkScheduler
296 } // namespace OHOS