1 /*
2 * Copyright (c) 2022-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 "res_sched_service_proxy.h"
17 #include "ipc_types.h" // for NO_ERROR
18 #include "ipc_util.h" // for WRITE_PARCEL
19 #include "iremote_object.h" // for IRemoteObject
20 #include "message_option.h" // for MessageOption, MessageOption::TF_ASYNC
21 #include "message_parcel.h" // for MessageParcel
22 #include "res_sched_errors.h" // for GET_RES_SCHED_SERVICE_FAILED
23 #include "res_sched_log.h" // for RESSCHED_LOGD, RESSCHED_LOGE
24 #include "res_sched_ipc_interface_code.h" // for ResourceScheduleInterfaceCode
25
26 namespace OHOS {
27 namespace ResourceSchedule {
28
SendRequestToRemote(const uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)29 int32_t ResSchedServiceProxy::SendRequestToRemote(const uint32_t code, MessageParcel &data, MessageParcel &reply,
30 MessageOption &option)
31 {
32 sptr<IRemoteObject> remote = Remote();
33 if (remote != nullptr) {
34 return remote->SendRequest(code, data, reply, option);
35 }
36
37 RESSCHED_LOGE("remote is null, code=%{public}u.", code);
38 return RES_SCHED_CONNECT_FAIL;
39 }
40
ReportData(uint32_t resType,int64_t value,const nlohmann::json & payload)41 void ResSchedServiceProxy::ReportData(uint32_t resType, int64_t value, const nlohmann::json& payload)
42 {
43 int32_t error;
44 MessageParcel data;
45 MessageParcel reply;
46 MessageOption option = { MessageOption::TF_ASYNC };
47 WriteParcelForReportData(resType, value, payload, data);
48 error = SendRequestToRemote(static_cast<uint32_t>(ResourceScheduleInterfaceCode::REPORT_DATA),
49 data, reply, option);
50 if (error != NO_ERROR) {
51 RESSCHED_LOGE("Send request error: %{public}d.", error);
52 return;
53 }
54 RESSCHED_LOGD("%{public}s, success.", __func__);
55 }
56
ReportSyncEvent(const uint32_t resType,const int64_t value,const nlohmann::json & payload,nlohmann::json & reply)57 int32_t ResSchedServiceProxy::ReportSyncEvent(const uint32_t resType, const int64_t value,
58 const nlohmann::json& payload, nlohmann::json& reply)
59 {
60 MessageParcel data;
61 WriteParcelForReportData(resType, value, payload, data);
62 MessageParcel response;
63 MessageOption option = { MessageOption::TF_SYNC };
64 int32_t ret = SendRequestToRemote(static_cast<uint32_t>(ResourceScheduleInterfaceCode::REPORT_SYNC_EVENT),
65 data, response, option);
66 if (ret != NO_ERROR) {
67 RESSCHED_LOGE("%{public}s: SendRequest fail=%{public}d.", __func__, ret);
68 return RES_SCHED_REQUEST_FAIL;
69 }
70
71 ret = response.ReadInt32();
72 if (ret == NO_ERROR && !StringToJson(response.ReadString(), reply)) {
73 RESSCHED_LOGE("%{public}s: parse reply fail.", __func__);
74 ret = RES_SCHED_DATA_ERROR;
75 }
76 RESSCHED_LOGD("%{public}s: ret=%{public}d.", __func__, ret);
77 return ret;
78 }
79
WriteParcelForReportData(const uint32_t resType,const int64_t value,const nlohmann::json & payload,MessageParcel & data)80 int32_t ResSchedServiceProxy::WriteParcelForReportData(const uint32_t resType, const int64_t value,
81 const nlohmann::json& payload, MessageParcel& data)
82 {
83 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), RES_SCHED_DATA_ERROR,
84 ResSchedServiceProxy);
85 WRITE_PARCEL(data, Uint32, resType, RES_SCHED_DATA_ERROR, ResSchedServiceProxy);
86 WRITE_PARCEL(data, Int64, value, RES_SCHED_DATA_ERROR, ResSchedServiceProxy);
87 WRITE_PARCEL(data, String, payload.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace),
88 RES_SCHED_DATA_ERROR, ResSchedServiceProxy);
89 return NO_ERROR;
90 }
91
StringToJson(const std::string & str,nlohmann::json & jsonObj)92 bool ResSchedServiceProxy::StringToJson(const std::string& str, nlohmann::json& jsonObj)
93 {
94 if (str.empty()) {
95 return true;
96 }
97 jsonObj = nlohmann::json::parse(str, nullptr, false);
98 if (jsonObj.is_discarded()) {
99 RESSCHED_LOGE("%{public}s: parse fail, str=%{public}s.", __func__, str.c_str());
100 return false;
101 }
102 if (!jsonObj.is_object()) {
103 RESSCHED_LOGE("%{public}s: str=%{public}s is not jsonObj.", __func__, str.c_str());
104 return false;
105 }
106 return true;
107 }
108
KillProcess(const nlohmann::json & payload)109 int32_t ResSchedServiceProxy::KillProcess(const nlohmann::json& payload)
110 {
111 int32_t error;
112 MessageParcel data;
113 MessageParcel reply;
114 MessageOption option = { MessageOption::TF_SYNC };
115 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), RES_SCHED_DATA_ERROR,
116 ResSchedServiceProxy);
117 WRITE_PARCEL(data, String, payload.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace),
118 RES_SCHED_DATA_ERROR, ResSchedServiceProxy);
119 error = SendRequestToRemote(static_cast<uint32_t>(ResourceScheduleInterfaceCode::KILL_PROCESS),
120 data, reply, option);
121 if (error != NO_ERROR) {
122 RESSCHED_LOGE("Send request error: %{public}d.", error);
123 return RES_SCHED_REQUEST_FAIL;
124 }
125 RESSCHED_LOGD("%{public}s, success.", __func__);
126 return reply.ReadInt32();
127 }
128
RegisterSystemloadNotifier(const sptr<IRemoteObject> & notifier)129 void ResSchedServiceProxy::RegisterSystemloadNotifier(const sptr<IRemoteObject>& notifier)
130 {
131 int32_t error;
132 MessageParcel data;
133 MessageParcel reply;
134 MessageOption option = { MessageOption::TF_SYNC };
135 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), void(), ResSchedServiceProxy);
136 WRITE_PARCEL(data, RemoteObject, notifier, void(), ResSchedServiceProxy);
137 error = SendRequestToRemote(static_cast<uint32_t>(ResourceScheduleInterfaceCode::REGISTER_SYSTEMLOAD_NOTIFIER),
138 data, reply, option);
139 if (error != NO_ERROR) {
140 RESSCHED_LOGE("Send request error: %{public}d.", error);
141 return;
142 }
143 RESSCHED_LOGD("%{public}s, success.", __func__);
144 }
145
RegisterEventListener(const sptr<IRemoteObject> & listener,uint32_t eventType,uint32_t group)146 void ResSchedServiceProxy::RegisterEventListener(const sptr<IRemoteObject>& listener,
147 uint32_t eventType, uint32_t group)
148 {
149 int32_t error;
150 MessageParcel data;
151 MessageParcel reply;
152 MessageOption option = { MessageOption::TF_SYNC };
153 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), void(), ResSchedServiceProxy);
154 WRITE_PARCEL(data, RemoteObject, listener, void(), ResSchedServiceProxy);
155 WRITE_PARCEL(data, Uint32, eventType, void(), ResSchedServiceProxy);
156 WRITE_PARCEL(data, Uint32, group, void(), ResSchedServiceProxy);
157 error = Remote()->SendRequest(static_cast<uint32_t>(ResourceScheduleInterfaceCode::REGISTER_EVENT_LISTENER),
158 data, reply, option);
159 if (error != NO_ERROR) {
160 RESSCHED_LOGE("%{public}s:Send request error: %{public}d.", __func__, error);
161 return;
162 }
163 RESSCHED_LOGD("%{public}s, success.", __func__);
164 }
165
UnRegisterEventListener(uint32_t eventType,uint32_t listenerGroup)166 void ResSchedServiceProxy::UnRegisterEventListener(uint32_t eventType, uint32_t listenerGroup)
167 {
168 int32_t error;
169 MessageParcel data;
170 MessageParcel reply;
171 MessageOption option = { MessageOption::TF_SYNC };
172 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), void(), ResSchedServiceProxy);
173 WRITE_PARCEL(data, Uint32, eventType, void(), ResSchedServiceProxy);
174 WRITE_PARCEL(data, Uint32, listenerGroup, void(), ResSchedServiceProxy);
175 error = Remote()->SendRequest(static_cast<uint32_t>(ResourceScheduleInterfaceCode::UNREGISTER_EVENT_LISTENER),
176 data, reply, option);
177 if (error != NO_ERROR) {
178 RESSCHED_LOGE("%{public}s:Send request error: %{public}d.", __func__, error);
179 return;
180 }
181 RESSCHED_LOGD("%{public}s, success.", __func__);
182 }
183
UnRegisterSystemloadNotifier()184 void ResSchedServiceProxy::UnRegisterSystemloadNotifier()
185 {
186 int32_t error;
187 MessageParcel data;
188 MessageParcel reply;
189 MessageOption option = { MessageOption::TF_SYNC };
190 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), void(), ResSchedServiceProxy);
191 error = SendRequestToRemote(
192 static_cast<uint32_t>(ResourceScheduleInterfaceCode::UNREGISTER_SYSTEMLOAD_NOTIFIER), data, reply, option);
193 if (error != NO_ERROR) {
194 RESSCHED_LOGE("Send request error: %{public}d.", error);
195 return;
196 }
197 RESSCHED_LOGD("%{public}s, success.", __func__);
198 }
199
GetSystemloadLevel()200 int32_t ResSchedServiceProxy::GetSystemloadLevel()
201 {
202 int32_t error;
203 MessageParcel data;
204 MessageParcel reply;
205 MessageOption option = { MessageOption::TF_SYNC };
206 WRITE_PARCEL(data, InterfaceToken, ResSchedServiceProxy::GetDescriptor(), RES_SCHED_DATA_ERROR,
207 ResSchedServiceProxy);
208 error = SendRequestToRemote(static_cast<uint32_t>(ResourceScheduleInterfaceCode::GET_SYSTEMLOAD_LEVEL),
209 data, reply, option);
210 if (error != NO_ERROR) {
211 RESSCHED_LOGE("Send request error: %{public}d.", error);
212 return RES_SCHED_REQUEST_FAIL;
213 }
214 RESSCHED_LOGD("%{public}s, success.", __func__);
215 return reply.ReadInt32();
216 }
217
IsAllowedAppPreload(const std::string & bundleName,int32_t preloadMode)218 bool ResSchedServiceProxy::IsAllowedAppPreload(const std::string& bundleName, int32_t preloadMode)
219 {
220 MessageParcel data;
221 MessageParcel reply;
222 MessageOption option = { MessageOption::TF_SYNC };
223 if (!data.WriteInterfaceToken(GetDescriptor())) {
224 return false;
225 }
226
227 WRITE_PARCEL(data, String, bundleName, false, ResSchedServiceProxy);
228 WRITE_PARCEL(data, Int32, preloadMode, false, ResSchedServiceProxy);
229
230 auto remote = Remote();
231 if (!remote) {
232 RESSCHED_LOGE("Get remote failed");
233 return false;
234 }
235
236 int32_t error = remote->SendRequest(static_cast<uint32_t>(ResourceScheduleInterfaceCode::TOUCH_DOWN_APP_PRELOAD),
237 data, reply, option);
238 if (error != NO_ERROR) {
239 RESSCHED_LOGE("Send request error: %{public}d.", error);
240 return false;
241 }
242
243 bool isAllowedPreload = false;
244 if (!reply.ReadBool(isAllowedPreload)) {
245 RESSCHED_LOGE("Read result failed");
246 return false;
247 }
248 RESSCHED_LOGD("%{public}s, success.", __func__);
249 return isAllowedPreload;
250 }
251 } // namespace ResourceSchedule
252 } // namespace OHOS
253