1 /*
2  * Copyright (c) 2021-2023 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 "form_supply_proxy.h"
17 
18 #include "appexecfwk_errors.h"
19 #include "fms_log_wrapper.h"
20 #include "form_constants.h"
21 #include "string_ex.h"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace {
26     static constexpr int32_t MAX_ALLOW_SIZE = 8 * 1024;
27 }
28 /**
29  * @brief Send form binding data from form provider to fms.
30  * @param providerFormInfo Form binding data.
31  * @param want input data.
32  * @return Returns ERR_OK on success, others on failure.
33  */
OnAcquire(const FormProviderInfo & formInfo,const Want & want)34 int FormSupplyProxy::OnAcquire(const FormProviderInfo &formInfo, const Want& want)
35 {
36     MessageParcel data;
37     if (!WriteInterfaceToken(data)) {
38         HILOG_ERROR("WriteInterfaceToken failed");
39         return ERR_APPEXECFWK_PARCEL_ERROR;
40     }
41     if (!data.WriteParcelable(&want)) {
42         HILOG_ERROR("write want failed");
43         return ERR_APPEXECFWK_PARCEL_ERROR;
44     }
45 
46     if (want.GetIntParam(Constants::PROVIDER_FLAG, ERR_OK) == ERR_OK) {
47         if (!data.WriteParcelable(&formInfo)) {
48             HILOG_ERROR("write formInfo failed");
49             return ERR_APPEXECFWK_PARCEL_ERROR;
50         }
51     }
52 
53     MessageParcel reply;
54     MessageOption option;
55     int error = SendTransactCmd(
56         IFormSupply::Message::TRANSACTION_FORM_ACQUIRED,
57         data,
58         reply,
59         option);
60     if (error != ERR_OK) {
61         HILOG_ERROR("SendRequest:%{public}d failed", error);
62     }
63     return error;
64 }
65 
66 
67 /**
68  * @brief Send other event  to fms.
69  * @param want input data.
70  * @return Returns ERR_OK on success, others on failure.
71  */
OnEventHandle(const Want & want)72 int FormSupplyProxy::OnEventHandle(const Want& want)
73 {
74     MessageParcel data;
75 
76     if (!WriteInterfaceToken(data)) {
77         HILOG_ERROR("write interface token failed");
78         return ERR_APPEXECFWK_PARCEL_ERROR;
79     }
80 
81     if (!data.WriteParcelable(&want)) {
82         HILOG_ERROR("write want failed");
83         return ERR_APPEXECFWK_PARCEL_ERROR;
84     }
85 
86     MessageParcel reply;
87     MessageOption option;
88     int error = SendTransactCmd(
89         IFormSupply::Message::TRANSACTION_EVENT_HANDLE,
90         data,
91         reply,
92         option);
93     if (error != ERR_OK) {
94         HILOG_ERROR("SendRequest:%{public}d failed", error);
95     }
96     return error;
97 }
98 
99 /**
100  * @brief Accept form state from form provider.
101  * @param state Form state.
102  * @param provider provider info.
103  * @param wantArg The want of onAcquireFormState.
104  * @param want input data.
105  * @return Returns ERR_OK on success, others on failure.
106  */
OnAcquireStateResult(FormState state,const std::string & provider,const Want & wantArg,const Want & want)107 int FormSupplyProxy::OnAcquireStateResult(FormState state, const std::string &provider, const Want &wantArg,
108                                           const Want &want)
109 {
110     MessageParcel data;
111     if (!WriteInterfaceToken(data)) {
112         HILOG_ERROR("WriteInterfaceToken failed");
113         return ERR_APPEXECFWK_PARCEL_ERROR;
114     }
115     if (!data.WriteInt32((int32_t) state)) {
116         HILOG_ERROR("write form state failed");
117         return ERR_APPEXECFWK_PARCEL_ERROR;
118     }
119     if (!data.WriteString(provider)) {
120         HILOG_ERROR("write providerStr failed");
121         return ERR_APPEXECFWK_PARCEL_ERROR;
122     }
123     if (!data.WriteParcelable(&wantArg)) {
124         HILOG_ERROR("write want failed");
125         return ERR_APPEXECFWK_PARCEL_ERROR;
126     }
127     if (!data.WriteParcelable(&want)) {
128         HILOG_ERROR("write want failed");
129         return ERR_APPEXECFWK_PARCEL_ERROR;
130     }
131 
132     MessageParcel reply;
133     MessageOption option;
134     int error = SendTransactCmd(
135         IFormSupply::Message::TRANSACTION_FORM_STATE_ACQUIRED,
136         data,
137         reply,
138         option);
139     if (error != ERR_OK) {
140         HILOG_ERROR("SendRequest:%{public}d failed", error);
141     }
142     return error;
143 }
144 
145 template<typename T>
GetParcelableInfos(MessageParcel & reply,std::vector<T> & parcelableInfos)146 int  FormSupplyProxy::GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos)
147 {
148     int32_t infoSize = reply.ReadInt32();
149     if (infoSize < 0 || infoSize > MAX_ALLOW_SIZE) {
150         HILOG_ERROR("invalid size:%{public}d", infoSize);
151         return ERR_APPEXECFWK_PARCEL_ERROR;
152     }
153     for (int32_t i = 0; i < infoSize; i++) {
154         std::unique_ptr<T> info(reply.ReadParcelable<T>());
155         if (!info) {
156             HILOG_ERROR("fail ReadParcelable<T>");
157             return ERR_INVALID_VALUE;
158         }
159         parcelableInfos.emplace_back(*info);
160     }
161     HILOG_INFO("success");
162     return ERR_OK;
163 }
164 
WriteInterfaceToken(MessageParcel & data)165 bool  FormSupplyProxy::WriteInterfaceToken(MessageParcel &data)
166 {
167     if (!data.WriteInterfaceToken(FormSupplyProxy::GetDescriptor())) {
168         HILOG_ERROR("fail write interface token failed");
169         return false;
170     }
171     return true;
172 }
173 
OnShareAcquire(int64_t formId,const std::string & remoteDeviceId,const AAFwk::WantParams & wantParams,int64_t requestCode,const bool & result)174 void FormSupplyProxy::OnShareAcquire(int64_t formId, const std::string &remoteDeviceId,
175     const AAFwk::WantParams &wantParams, int64_t requestCode, const bool &result)
176 {
177     MessageParcel data;
178     MessageParcel reply;
179     MessageOption option;
180 
181     if (!WriteInterfaceToken(data)) {
182         HILOG_ERROR("fail WriteInterfaceToken");
183         return;
184     }
185     if (!data.WriteInt64(formId)) {
186         HILOG_ERROR("write formId failed");
187         return;
188     }
189     if (!data.WriteString(remoteDeviceId)) {
190         HILOG_ERROR("write remoteDeviceId failed");
191         return;
192     }
193     if (!data.WriteParcelable(&wantParams)) {
194         HILOG_ERROR("write wantParams failed");
195         return;
196     }
197     if (!data.WriteInt64(requestCode)) {
198         HILOG_ERROR("write requestCode failed");
199         return;
200     }
201     if (!data.WriteBool(result)) {
202         HILOG_ERROR("write formResult failed");
203         return;
204     }
205     auto error = SendTransactCmd(
206         IFormSupply::Message::TRANSACTION_FORM_SHARE_ACQUIRED,
207         data,
208         reply,
209         option);
210     if (error != ERR_OK) {
211         HILOG_ERROR("SendRequest:%{public}d failed", error);
212     }
213 }
214 
OnAcquireDataResult(const AAFwk::WantParams & wantParams,int64_t requestCode)215 int FormSupplyProxy::OnAcquireDataResult(const AAFwk::WantParams &wantParams, int64_t requestCode)
216 {
217     MessageParcel data;
218     MessageParcel reply;
219     MessageOption option;
220 
221     if (!WriteInterfaceToken(data)) {
222         HILOG_ERROR("fail WriteInterfaceToken");
223         return ERR_APPEXECFWK_PARCEL_ERROR;
224     }
225     if (!data.WriteParcelable(&wantParams)) {
226         HILOG_ERROR("fail write form wantParams");
227         return ERR_APPEXECFWK_PARCEL_ERROR;
228     }
229     if (!data.WriteInt64(requestCode)) {
230         HILOG_ERROR("write formRequestCode failed");
231         return ERR_APPEXECFWK_PARCEL_ERROR;
232     }
233     auto error = SendTransactCmd(
234         IFormSupply::Message::TRANSACTION_FORM_ACQUIRED_DATA,
235         data,
236         reply,
237         option);
238     if (error != ERR_OK) {
239         HILOG_ERROR("SendRequest:%{public}d failed", error);
240     }
241     return error;
242 }
243 
OnRenderTaskDone(int64_t formId,const Want & want)244 int32_t FormSupplyProxy::OnRenderTaskDone(int64_t formId, const Want &want)
245 {
246     MessageParcel data;
247 
248     if (!WriteInterfaceToken(data)) {
249         HILOG_ERROR("write interface token fail");
250         return ERR_APPEXECFWK_PARCEL_ERROR;
251     }
252 
253     if (!data.WriteInt64(formId)) {
254         HILOG_ERROR("write formId fail");
255         return ERR_APPEXECFWK_PARCEL_ERROR;
256     }
257 
258     if (!data.WriteParcelable(&want)) {
259         HILOG_ERROR("write want failed");
260         return ERR_APPEXECFWK_PARCEL_ERROR;
261     }
262 
263     MessageParcel reply;
264     MessageOption option;
265     int error = SendTransactCmd(
266         IFormSupply::Message::TRANSACTION_FORM_RENDER_TASK_DONE,
267         data,
268         reply,
269         option);
270     if (error != ERR_OK) {
271         HILOG_ERROR("SendRequest:%{public}d failed", error);
272     }
273     return error;
274 }
275 
OnStopRenderingTaskDone(int64_t formId,const Want & want)276 int32_t FormSupplyProxy::OnStopRenderingTaskDone(int64_t formId, const Want &want)
277 {
278     MessageParcel data;
279 
280     if (!WriteInterfaceToken(data)) {
281         HILOG_ERROR("error to write interface token");
282         return ERR_APPEXECFWK_PARCEL_ERROR;
283     }
284 
285     if (!data.WriteInt64(formId)) {
286         HILOG_ERROR("error to write formId");
287         return ERR_APPEXECFWK_PARCEL_ERROR;
288     }
289 
290     if (!data.WriteParcelable(&want)) {
291         HILOG_ERROR("write want failed");
292         return ERR_APPEXECFWK_PARCEL_ERROR;
293     }
294 
295     MessageParcel reply;
296     MessageOption option;
297     int error = SendTransactCmd(
298         IFormSupply::Message::TRANSACTION_FORM_STOP_RENDERING_TASK_DONE,
299         data,
300         reply,
301         option);
302     if (error != ERR_OK) {
303         HILOG_ERROR("SendRequest:%{public}d failed", error);
304     }
305     return error;
306 }
307 
OnRenderingBlock(const std::string & bundleName)308 int32_t FormSupplyProxy::OnRenderingBlock(const std::string &bundleName)
309 {
310     MessageParcel data;
311     if (!WriteInterfaceToken(data)) {
312         HILOG_ERROR("OnRenderingBlock failed to write interface token");
313         return ERR_APPEXECFWK_PARCEL_ERROR;
314     }
315 
316     if (!data.WriteString(bundleName)) {
317         HILOG_ERROR("OnRenderingBlock failed to write bundleName");
318         return ERR_APPEXECFWK_PARCEL_ERROR;
319     }
320 
321     MessageParcel reply;
322     MessageOption option;
323     int error = SendTransactCmd(
324         IFormSupply::Message::TRANSACTION_FORM_RENDERING_BLOCK,
325         data,
326         reply,
327         option);
328     if (error != ERR_OK) {
329         HILOG_ERROR("SendRequest:%{public}d failed", error);
330     }
331     return error;
332 }
333 
SendTransactCmd(IFormSupply::Message code,MessageParcel & data,MessageParcel & reply,MessageOption & option)334 int FormSupplyProxy::SendTransactCmd(IFormSupply::Message code, MessageParcel &data,
335     MessageParcel &reply, MessageOption &option)
336 {
337     sptr<IRemoteObject> remote = Remote();
338     if (!remote) {
339         HILOG_ERROR("get remoteObject failed, cmd:%{public}d", code);
340         return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
341     }
342     int32_t result = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
343     if (result != ERR_OK) {
344         HILOG_ERROR("SendRequest failed:%{public}d, cmd:%{public}d", result, code);
345         return result;
346     }
347     return ERR_OK;
348 }
349 
OnRecycleForm(const int64_t & formId,const Want & want)350 int32_t FormSupplyProxy::OnRecycleForm(const int64_t &formId, const Want &want)
351 {
352     MessageParcel data;
353     if (!WriteInterfaceToken(data)) {
354         HILOG_ERROR("error to write interface token");
355         return ERR_APPEXECFWK_PARCEL_ERROR;
356     }
357 
358     if (!data.WriteInt64(formId)) {
359         HILOG_ERROR("error to write formId");
360         return ERR_APPEXECFWK_PARCEL_ERROR;
361     }
362 
363     if (!data.WriteParcelable(&want)) {
364         HILOG_ERROR("write want failed");
365         return ERR_APPEXECFWK_PARCEL_ERROR;
366     }
367 
368     MessageParcel reply;
369     MessageOption option(MessageOption::TF_ASYNC);
370     int error = SendTransactCmd(
371         IFormSupply::Message::TRANSACTION_FORM_RECYCLE_FORM,
372         data,
373         reply,
374         option);
375     if (error != ERR_OK) {
376         HILOG_ERROR("SendRequest:%{public}d failed", error);
377     }
378     return error;
379 }
380 
OnRecoverFormsByConfigUpdate(std::vector<int64_t> & formIds)381 int32_t FormSupplyProxy::OnRecoverFormsByConfigUpdate(std::vector<int64_t> &formIds)
382 {
383     MessageParcel data;
384     if (!WriteInterfaceToken(data)) {
385         HILOG_ERROR("error to write interface token");
386         return ERR_APPEXECFWK_PARCEL_ERROR;
387     }
388 
389     if (!data.WriteInt64Vector(formIds)) {
390         HILOG_ERROR("error to write formIds");
391         return ERR_APPEXECFWK_PARCEL_ERROR;
392     }
393 
394     MessageParcel reply;
395     MessageOption option(MessageOption::TF_ASYNC);
396     int error = SendTransactCmd(
397         IFormSupply::Message::TRANSACTION_FORM_RECOVER_FORM_BY_CONFIG_UPDATE,
398         data,
399         reply,
400         option);
401     if (error != ERR_OK) {
402         HILOG_ERROR("SendRequest:%{public}d failed", error);
403     }
404     return error;
405 }
406 
OnNotifyRefreshForm(const int64_t & formId)407 int32_t FormSupplyProxy::OnNotifyRefreshForm(const int64_t &formId)
408 {
409     MessageParcel data;
410     // write in token to help identify which stub to be called.
411     if (!WriteInterfaceToken(data)) {
412         HILOG_ERROR("error to write interface token");
413         return ERR_APPEXECFWK_PARCEL_ERROR;
414     }
415 
416     if (!data.WriteInt64(formId)) {
417         HILOG_ERROR("error to write formId");
418         return ERR_APPEXECFWK_PARCEL_ERROR;
419     }
420     // send request.
421     MessageParcel reply;
422     MessageOption option(MessageOption::TF_ASYNC);
423     int error = SendTransactCmd(
424         IFormSupply::Message::TRANSACTION_NOTIFY_REFRESH,
425         data,
426         reply,
427         option);
428     if (error != ERR_OK) {
429         HILOG_ERROR("SendRequest:%{public}d failed", error);
430     }
431     return error;
432 }
433 }  // namespace AppExecFwk
434 }  // namespace OHOS
435