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 #include "form_provider_proxy.h"
16 #include "appexecfwk_errors.h"
17 #include "string_ex.h"
18 
19 namespace OHOS {
20 namespace AppExecFwk {
21 namespace {
22     static constexpr int32_t MAX_ALLOW_SIZE = 8 * 1024;
23 }
AcquireProviderFormInfo(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)24 int FormProviderProxy::AcquireProviderFormInfo(
25     const FormJsInfo &formJsInfo,
26     const Want &want,
27     const sptr<IRemoteObject> &callerToken)
28 {
29     int error;
30     MessageParcel data;
31     MessageParcel reply;
32     MessageOption option(MessageOption::TF_ASYNC);
33 
34     if (!WriteInterfaceToken(data)) {
35         HILOG_ERROR("write interface token failed");
36         return ERR_APPEXECFWK_PARCEL_ERROR;
37     }
38     if (!data.WriteParcelable(&formJsInfo)) {
39         HILOG_ERROR("write formJsInfo error");
40         return ERR_APPEXECFWK_PARCEL_ERROR;
41     }
42     if (!data.WriteParcelable(&want)) {
43         HILOG_ERROR("write want fail");
44         return ERR_APPEXECFWK_PARCEL_ERROR;
45     }
46 
47     if (!data.WriteRemoteObject(callerToken)) {
48         HILOG_ERROR("write callerToken fail");
49         return ERR_APPEXECFWK_PARCEL_ERROR;
50     }
51 
52     error = SendTransactCmd(
53         IFormProvider::Message::FORM_ACQUIRE_PROVIDER_FORM_INFO,
54         data,
55         reply,
56         option);
57     if (error != ERR_OK) {
58         HILOG_ERROR("SendRequest:%{public}d failed", error);
59         return error;
60     }
61     return ERR_OK;
62 }
63 
64 /**
65  * @brief Notify provider when the form was deleted.
66  * @param formIds The id list of forms.
67  * @param want Indicates the structure containing form info.
68  * @param callerToken Caller ability token.
69  * @return Returns ERR_OK on success, others on failure.
70  */
NotifyFormDelete(const int64_t formId,const Want & want,const sptr<IRemoteObject> & callerToken)71 int FormProviderProxy::NotifyFormDelete(const int64_t formId, const Want &want, const sptr<IRemoteObject> &callerToken)
72 {
73     int error;
74     MessageParcel data;
75     MessageParcel reply;
76     MessageOption option(MessageOption::TF_ASYNC);
77 
78     if (!WriteInterfaceToken(data)) {
79         HILOG_ERROR("error to write interface token");
80         return ERR_APPEXECFWK_PARCEL_ERROR;
81     }
82     if (!data.WriteInt64(formId)) {
83         HILOG_ERROR("error to write formId");
84         return ERR_APPEXECFWK_PARCEL_ERROR;
85     }
86     if (!data.WriteParcelable(&want)) {
87         HILOG_ERROR("error to write want");
88         return ERR_APPEXECFWK_PARCEL_ERROR;
89     }
90     if (!data.WriteRemoteObject(callerToken)) {
91         HILOG_ERROR("error to write callerToken");
92         return ERR_APPEXECFWK_PARCEL_ERROR;
93     }
94 
95     error = SendTransactCmd(
96         IFormProvider::Message::FORM_PROVIDER_NOTIFY_FORM_DELETE,
97         data,
98         reply,
99         option);
100     if (error != ERR_OK) {
101         HILOG_ERROR("SendRequest:%{public}d failed", error);
102         return error;
103     }
104     return ERR_OK;
105 }
106 /**
107  * @brief Notify provider when the forms was deleted.
108  * @param formIds The id list of forms.
109  * @param want Indicates the structure containing form info.
110  * @param callerToken Caller ability token.
111  * @return Returns ERR_OK on success, others on failure.
112  */
NotifyFormsDelete(const std::vector<int64_t> & formIds,const Want & want,const sptr<IRemoteObject> & callerToken)113 int FormProviderProxy::NotifyFormsDelete(
114     const std::vector<int64_t> &formIds,
115     const Want &want,
116     const sptr<IRemoteObject> &callerToken)
117 {
118     int error;
119     MessageParcel data;
120     MessageParcel reply;
121     MessageOption option(MessageOption::TF_ASYNC);
122 
123     if (!WriteInterfaceToken(data)) {
124         HILOG_ERROR("write interface token failed");
125         return ERR_APPEXECFWK_PARCEL_ERROR;
126     }
127     if (!data.WriteInt64Vector(formIds)) {
128         HILOG_ERROR("write formIds failed");
129         return ERR_APPEXECFWK_PARCEL_ERROR;
130     }
131     if (!data.WriteParcelable(&want)) {
132         HILOG_ERROR("write to want error");
133         return ERR_APPEXECFWK_PARCEL_ERROR;
134     }
135     if (!data.WriteRemoteObject(callerToken)) {
136         HILOG_ERROR("write to callerToken error");
137         return ERR_APPEXECFWK_PARCEL_ERROR;
138     }
139 
140     error = SendTransactCmd(
141         IFormProvider::Message::FORM_PROVIDER_NOTIFY_FORMS_DELETE,
142         data,
143         reply,
144         option);
145     if (error != ERR_OK) {
146         HILOG_ERROR("SendRequest:%{public}d failed", error);
147         return error;
148     }
149     return ERR_OK;
150 }
151 
152 /**
153  * @brief Notify provider when the form need update.
154  * @param formId The Id of the form.
155  * @param want Indicates the structure containing form info.
156  * @param callerToken Caller ability token.
157  * @return Returns ERR_OK on success, others on failure.
158  */
NotifyFormUpdate(const int64_t formId,const Want & want,const sptr<IRemoteObject> & callerToken)159 int FormProviderProxy::NotifyFormUpdate(const int64_t formId, const Want &want, const sptr<IRemoteObject> &callerToken)
160 {
161     int error;
162     MessageParcel data;
163     MessageParcel reply;
164     MessageOption option(MessageOption::TF_ASYNC);
165 
166     if (!WriteInterfaceToken(data)) {
167         HILOG_ERROR("write interface token failed");
168         return ERR_APPEXECFWK_PARCEL_ERROR;
169     }
170     if (!data.WriteInt64(formId)) {
171         HILOG_ERROR("write formId failed");
172         return ERR_APPEXECFWK_PARCEL_ERROR;
173     }
174 
175     if (!data.WriteParcelable(&want)) {
176         HILOG_ERROR("write want failed");
177         return ERR_APPEXECFWK_PARCEL_ERROR;
178     }
179 
180     if (!data.WriteRemoteObject(callerToken)) {
181         HILOG_ERROR("write callerToken failed");
182         return ERR_APPEXECFWK_PARCEL_ERROR;
183     }
184 
185     error = SendTransactCmd(
186         IFormProvider::Message::FORM_PROVIDER_NOTIFY_FORM_UPDATE,
187         data,
188         reply,
189         option);
190     if (error != ERR_OK) {
191         HILOG_ERROR("SendRequest:%{public}d failed", error);
192         return error;
193     }
194     return ERR_OK;
195 }
196 
197 /**
198  * @brief Event notify when change the form visible.
199  *
200  * @param formIds The vector of form ids.
201  * @param formVisibleType The form visible type, including FORM_VISIBLE and FORM_INVISIBLE.
202  * @param want Indicates the structure containing form info.
203  * @param callerToken Caller ability token.
204  * @return Returns ERR_OK on success, others on failure.
205  */
EventNotify(const std::vector<int64_t> & formIds,const int32_t formVisibleType,const Want & want,const sptr<IRemoteObject> & callerToken)206 int FormProviderProxy::EventNotify(const std::vector<int64_t> &formIds, const int32_t formVisibleType,
207     const Want &want, const sptr<IRemoteObject> &callerToken)
208 {
209     int error;
210     MessageParcel data;
211     MessageParcel reply;
212     MessageOption option(MessageOption::TF_ASYNC);
213 
214     if (!WriteInterfaceToken(data)) {
215         HILOG_ERROR("write interface token failed");
216         return ERR_APPEXECFWK_PARCEL_ERROR;
217     }
218 
219     if (!data.WriteInt64Vector(formIds)) {
220         HILOG_ERROR("fail write formIds");
221         return ERR_APPEXECFWK_PARCEL_ERROR;
222     }
223 
224     if (!data.WriteInt32(formVisibleType)) {
225         HILOG_ERROR("fail write formVisibleType");
226         return ERR_APPEXECFWK_PARCEL_ERROR;
227     }
228 
229     if (!data.WriteParcelable(&want)) {
230         HILOG_ERROR("errpr to write want");
231         return ERR_APPEXECFWK_PARCEL_ERROR;
232     }
233 
234     if (!data.WriteRemoteObject(callerToken)) {
235         HILOG_ERROR("error to write callerToken");
236         return ERR_APPEXECFWK_PARCEL_ERROR;
237     }
238 
239     error = SendTransactCmd(
240         IFormProvider::Message::FORM_PROVIDER_EVENT_NOTIFY,
241         data,
242         reply,
243         option);
244     if (error != ERR_OK) {
245         HILOG_ERROR("SendRequest:%{public}d failed", error);
246         return error;
247     }
248     return ERR_OK;
249 }
250 
251 /**
252  * @brief Notify provider when the temp form was cast to normal form.
253  * @param formId The Id of the form to update.
254  * @param want Indicates the structure containing form info.
255  * @param callerToken Caller ability token.
256  * @return Returns ERR_OK on success, others on failure.
257  */
NotifyFormCastTempForm(const int64_t formId,const Want & want,const sptr<IRemoteObject> & callerToken)258 int FormProviderProxy::NotifyFormCastTempForm(
259     const int64_t formId,
260     const Want &want,
261     const sptr<IRemoteObject> &callerToken)
262 {
263     int error;
264     MessageParcel data;
265     MessageParcel reply;
266     MessageOption option(MessageOption::TF_ASYNC);
267 
268     if (!WriteInterfaceToken(data)) {
269         HILOG_ERROR("write interface token failed");
270         return ERR_APPEXECFWK_PARCEL_ERROR;
271     }
272 
273     if (!data.WriteInt64(formId)) {
274         HILOG_ERROR("write formId failed");
275         return ERR_APPEXECFWK_PARCEL_ERROR;
276     }
277     if (!data.WriteParcelable(&want)) {
278         HILOG_ERROR("write want failed");
279         return ERR_APPEXECFWK_PARCEL_ERROR;
280     }
281     if (!data.WriteRemoteObject(callerToken)) {
282         HILOG_ERROR("write callerToken failed");
283         return ERR_APPEXECFWK_PARCEL_ERROR;
284     }
285 
286     error = SendTransactCmd(
287         IFormProvider::Message::FORM_PROVIDER_NOTIFY_TEMP_FORM_CAST,
288         data,
289         reply,
290         option);
291     if (error != ERR_OK) {
292         HILOG_ERROR("SendRequest:%{public}d failed", error);
293         return error;
294     }
295     return ERR_OK;
296 }
297 
298 /**
299  * @brief Fire message event to form provider.
300  * @param formId The Id of the from.
301  * @param message Event message.
302  * @param want The want of the request.
303  * @param callerToken Form provider proxy object.
304  * @return Returns ERR_OK on success, others on failure.
305  */
FireFormEvent(const int64_t formId,const std::string & message,const Want & want,const sptr<IRemoteObject> & callerToken)306 int FormProviderProxy::FireFormEvent(
307     const int64_t formId,
308     const std::string &message,
309     const Want &want,
310     const sptr<IRemoteObject> &callerToken)
311 {
312     MessageParcel data;
313     if (!WriteInterfaceToken(data)) {
314         HILOG_ERROR("write interface token failed");
315         return ERR_APPEXECFWK_PARCEL_ERROR;
316     }
317     if (!data.WriteInt64(formId)) {
318         HILOG_ERROR("write formId failed");
319         return ERR_APPEXECFWK_PARCEL_ERROR;
320     }
321     if (!data.WriteString(message)) {
322         HILOG_ERROR("fail write message");
323         return ERR_APPEXECFWK_PARCEL_ERROR;
324     }
325     if (!data.WriteParcelable(&want)) {
326         HILOG_ERROR("write to want failed");
327         return ERR_APPEXECFWK_PARCEL_ERROR;
328     }
329     if (!data.WriteRemoteObject(callerToken)) {
330         HILOG_ERROR("write to callerToken failed");
331         return ERR_APPEXECFWK_PARCEL_ERROR;
332     }
333     MessageParcel reply;
334     MessageOption option(MessageOption::TF_ASYNC);
335     int error = SendTransactCmd(
336         IFormProvider::Message::FORM_PROVIDER_EVENT_MESSAGE,
337         data,
338         reply,
339         option);
340     if (error != ERR_OK) {
341         HILOG_ERROR("SendRequest:%{public}d failed", error);
342         return error;
343     }
344     return ERR_OK;
345 }
346 
347 /**
348  * @brief Acquire form state to form provider.
349  * @param wantArg The want of onAcquireFormState.
350  * @param provider The provider info.
351  * @param want The want of the request.
352  * @param callerToken Form provider proxy object.
353  * @return Returns ERR_OK on success, others on failure.
354  */
AcquireState(const Want & wantArg,const std::string & provider,const Want & want,const sptr<IRemoteObject> & callerToken)355 int FormProviderProxy::AcquireState(const Want &wantArg, const std::string &provider, const Want &want,
356                                     const sptr<IRemoteObject> &callerToken)
357 {
358     int error;
359     MessageParcel data;
360     MessageParcel reply;
361     MessageOption option(MessageOption::TF_ASYNC);
362 
363     if (!WriteInterfaceToken(data)) {
364         HILOG_ERROR("write interface token failed");
365         return ERR_APPEXECFWK_PARCEL_ERROR;
366     }
367 
368     if (!data.WriteParcelable(&wantArg)) {
369         HILOG_ERROR("write wantArg failed");
370         return ERR_APPEXECFWK_PARCEL_ERROR;
371     }
372     if (!data.WriteString(provider)) {
373         HILOG_ERROR("write string failed");
374         return ERR_APPEXECFWK_PARCEL_ERROR;
375     }
376     if (!data.WriteParcelable(&want)) {
377         HILOG_ERROR("write want failed");
378         return ERR_APPEXECFWK_PARCEL_ERROR;
379     }
380     if (!data.WriteRemoteObject(callerToken)) {
381         HILOG_ERROR("write callerToken failed");
382         return ERR_APPEXECFWK_PARCEL_ERROR;
383     }
384 
385     error = SendTransactCmd(
386         IFormProvider::Message::FORM_PROVIDER_NOTIFY_STATE_ACQUIRE,
387         data,
388         reply,
389         option);
390     if (error != ERR_OK) {
391         HILOG_ERROR("SendRequest:%{public}d failed", error);
392         return error;
393     }
394     return ERR_OK;
395 }
396 
AcquireFormData(int64_t formId,const sptr<IRemoteObject> & formSupplyCallback,int64_t requestCode)397 int32_t FormProviderProxy::AcquireFormData(int64_t formId, const sptr<IRemoteObject> &formSupplyCallback,
398                                            int64_t requestCode)
399 {
400     MessageParcel data;
401     MessageParcel reply;
402     MessageOption option(MessageOption::TF_ASYNC);
403 
404     if (!WriteInterfaceToken(data)) {
405         HILOG_ERROR("write interface token failed");
406         return ERR_APPEXECFWK_PARCEL_ERROR;
407     }
408 
409     if (!data.WriteInt64(formId)) {
410         HILOG_ERROR("write formId failed");
411         return ERR_APPEXECFWK_PARCEL_ERROR;
412     }
413 
414     if (!data.WriteRemoteObject(formSupplyCallback)) {
415         HILOG_ERROR("fail write formSupplyCallback");
416         return ERR_APPEXECFWK_PARCEL_ERROR;
417     }
418 
419     if (!data.WriteInt64(requestCode)) {
420         HILOG_ERROR("write requestCode failed");
421         return ERR_APPEXECFWK_PARCEL_ERROR;
422     }
423     int32_t result = SendTransactCmd(
424         IFormProvider::Message::FORM_ACQUIRE_PROVIDER_FOMR_DATA,
425         data,
426         reply,
427         option);
428     if (result != ERR_OK) {
429         HILOG_ERROR("error to SendRequest:%{public}d", result);
430         return result;
431     }
432 
433     auto retval = reply.ReadInt32();
434     if (retval != ERR_OK) {
435         HILOG_ERROR("error to replyData:%{public}d", retval);
436     }
437 
438     return retval;
439 }
440 
441 template<typename T>
GetParcelableInfos(MessageParcel & reply,std::vector<T> & parcelableInfos)442 int  FormProviderProxy::GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos)
443 {
444     int32_t infoSize = reply.ReadInt32();
445     if (infoSize < 0 || infoSize > MAX_ALLOW_SIZE) {
446         HILOG_ERROR("invalid size:%{public}d", infoSize);
447         return ERR_APPEXECFWK_PARCEL_ERROR;
448     }
449     for (int32_t i = 0; i < infoSize; i++) {
450         std::unique_ptr<T> info(reply.ReadParcelable<T>());
451         if (!info) {
452             HILOG_ERROR("read Parcelable infos failed");
453             return ERR_NULL_OBJECT;
454         }
455         parcelableInfos.emplace_back(*info);
456     }
457     HILOG_INFO("get success");
458     return ERR_OK;
459 }
460 
WriteInterfaceToken(MessageParcel & data)461 bool  FormProviderProxy::WriteInterfaceToken(MessageParcel &data)
462 {
463     if (!data.WriteInterfaceToken(FormProviderProxy::GetDescriptor())) {
464         HILOG_ERROR("write interface token failed");
465         return false;
466     }
467     return true;
468 }
469 
AcquireShareFormData(int64_t formId,const std::string & remoteDeviceId,const sptr<IRemoteObject> & formSupplyCallback,int64_t requestCode)470 int32_t FormProviderProxy::AcquireShareFormData(int64_t formId, const std::string &remoteDeviceId,
471     const sptr<IRemoteObject> &formSupplyCallback, int64_t requestCode)
472 {
473     MessageParcel data;
474     MessageParcel reply;
475     MessageOption option(MessageOption::TF_ASYNC);
476 
477     if (!WriteInterfaceToken(data)) {
478         HILOG_ERROR("write interface token failed");
479         return ERR_APPEXECFWK_PARCEL_ERROR;
480     }
481 
482     if (!data.WriteInt64(formId)) {
483         HILOG_ERROR("write formId failed");
484         return ERR_APPEXECFWK_PARCEL_ERROR;
485     }
486 
487     if (!data.WriteString(remoteDeviceId)) {
488         HILOG_ERROR("fail write remoteDeviceId");
489         return ERR_APPEXECFWK_PARCEL_ERROR;
490     }
491 
492     if (!data.WriteRemoteObject(formSupplyCallback)) {
493         HILOG_ERROR("fail write formSupplyCallback");
494         return ERR_APPEXECFWK_PARCEL_ERROR;
495     }
496 
497     if (!data.WriteInt64(requestCode)) {
498         HILOG_ERROR("write requestCode failed");
499         return ERR_APPEXECFWK_PARCEL_ERROR;
500     }
501     int32_t result = SendTransactCmd(
502         IFormProvider::Message::FORM_ACQUIRE_PROVIDER_SHARE_FOMR_INFO,
503         data,
504         reply,
505         option);
506     if (result != ERR_OK) {
507         HILOG_ERROR("fail SendRequest:%{public}d", result);
508         return result;
509     }
510 
511     auto retval = reply.ReadInt32();
512     if (retval != ERR_OK) {
513         HILOG_ERROR("fail replyData:%{public}d", retval);
514     }
515 
516     return retval;
517 }
518 
SendTransactCmd(IFormProvider::Message code,MessageParcel & data,MessageParcel & reply,MessageOption & option)519 int FormProviderProxy::SendTransactCmd(IFormProvider::Message code, MessageParcel &data,
520     MessageParcel &reply, MessageOption &option)
521 {
522     sptr<IRemoteObject> remote = Remote();
523     if (remote == nullptr) {
524         HILOG_ERROR("null remote");
525         return ERR_NULL_OBJECT;
526     }
527 
528     int ret = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
529     if (ret != ERR_OK) {
530         HILOG_ERROR("SendRequest fail.code= %{public}d,ret= %{public}d", code, ret);
531         return ret;
532     }
533     return ERR_OK;
534 }
535 
536 }  // namespace AppExecFwk
537 }  // namespace OHOS
538