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