1 /*
2  * Copyright (c) 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_render_proxy.h"
16 
17 #include <utility>
18 
19 #include "appexecfwk_errors.h"
20 #include "fms_log_wrapper.h"
21 #include "string_ex.h"
22 
23 namespace OHOS {
24 namespace AppExecFwk {
RenderForm(const FormJsInfo & formJsInfo,const Want & want,sptr<IRemoteObject> callerToken)25 int32_t FormRenderProxy::RenderForm(const FormJsInfo &formJsInfo, const Want &want,
26     sptr<IRemoteObject> callerToken)
27 {
28     MessageParcel data;
29     MessageParcel reply;
30     MessageOption option(MessageOption::TF_SYNC);
31 
32     if (!WriteInterfaceToken(data)) {
33         HILOG_ERROR("write interface token failed");
34         return ERR_APPEXECFWK_PARCEL_ERROR;
35     }
36     if (!data.WriteParcelable(&formJsInfo)) {
37         HILOG_ERROR("write formJsInfo error");
38         return ERR_APPEXECFWK_PARCEL_ERROR;
39     }
40     if (!data.WriteParcelable(&want)) {
41         HILOG_ERROR("write want error");
42         return ERR_APPEXECFWK_PARCEL_ERROR;
43     }
44 
45     if (!data.WriteRemoteObject(callerToken)) {
46         HILOG_ERROR("write callerToken error");
47         return ERR_APPEXECFWK_PARCEL_ERROR;
48     }
49 
50     int error = SendTransactCmd(
51         IFormRender::Message::FORM_RENDER_RENDER_FORM,
52         data,
53         reply,
54         option);
55     if (error != ERR_OK) {
56         HILOG_ERROR("error to SendRequest:%{public}d", error);
57         return error;
58     }
59     return ERR_OK;
60 }
61 
StopRenderingForm(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)62 int32_t FormRenderProxy::StopRenderingForm(const FormJsInfo &formJsInfo, const Want &want,
63     const sptr<IRemoteObject> &callerToken)
64 {
65     MessageParcel data;
66     MessageParcel reply;
67     MessageOption option(MessageOption::TF_ASYNC);
68 
69     if (!WriteInterfaceToken(data)) {
70         HILOG_ERROR("write interface token failed");
71         return ERR_APPEXECFWK_PARCEL_ERROR;
72     }
73     if (!data.WriteParcelable(&formJsInfo)) {
74         HILOG_ERROR("write formJsInfo error");
75         return ERR_APPEXECFWK_PARCEL_ERROR;
76     }
77     if (!data.WriteParcelable(&want)) {
78         HILOG_ERROR("write want failed");
79         return ERR_APPEXECFWK_PARCEL_ERROR;
80     }
81 
82     if (!data.WriteRemoteObject(callerToken)) {
83         HILOG_ERROR("write callerToken failed");
84         return ERR_APPEXECFWK_PARCEL_ERROR;
85     }
86 
87     int error = SendTransactCmd(
88         IFormRender::Message::FORM_RENDER_STOP_RENDERING_FORM,
89         data,
90         reply,
91         option);
92     if (error != ERR_OK) {
93         HILOG_ERROR("SendRequest:%{public}d failed", error);
94         return error;
95     }
96     return ERR_OK;
97 }
98 
CleanFormHost(const sptr<IRemoteObject> & hostToken)99 int32_t FormRenderProxy::CleanFormHost(const sptr<IRemoteObject> &hostToken)
100 {
101     MessageParcel data;
102     MessageParcel reply;
103     MessageOption option(MessageOption::TF_ASYNC);
104 
105     if (!WriteInterfaceToken(data)) {
106         HILOG_ERROR("write interface token failed");
107         return ERR_APPEXECFWK_PARCEL_ERROR;
108     }
109 
110     if (!data.WriteRemoteObject(hostToken)) {
111         HILOG_ERROR("fail write hostToken");
112         return ERR_APPEXECFWK_PARCEL_ERROR;
113     }
114 
115     int error = SendTransactCmd(
116         IFormRender::Message::FORM_RENDER_FORM_HOST_DIED,
117         data,
118         reply,
119         option);
120     if (error != ERR_OK) {
121         HILOG_ERROR("SendRequest:%{public}d failed", error);
122         return error;
123     }
124     return ERR_OK;
125 }
126 
WriteInterfaceToken(MessageParcel & data)127 bool FormRenderProxy::WriteInterfaceToken(MessageParcel &data)
128 {
129     if (!data.WriteInterfaceToken(FormRenderProxy::GetDescriptor())) {
130         HILOG_ERROR("write interface token failed");
131         return false;
132     }
133     return true;
134 }
135 
ReleaseRenderer(int64_t formId,const std::string & compId,const std::string & uid)136 int32_t FormRenderProxy::ReleaseRenderer(
137     int64_t formId, const std::string &compId, const std::string &uid)
138 {
139     MessageParcel data;
140     MessageParcel reply;
141     MessageOption option(MessageOption::TF_ASYNC);
142 
143     if (!WriteInterfaceToken(data)) {
144         HILOG_ERROR("error to write interface token");
145         return ERR_APPEXECFWK_PARCEL_ERROR;
146     }
147     if (!data.WriteInt64(formId)) {
148         HILOG_ERROR("write formId failed");
149         return ERR_APPEXECFWK_PARCEL_ERROR;
150     }
151     if (!data.WriteString(compId)) {
152         HILOG_ERROR("write compId failed");
153         return ERR_APPEXECFWK_PARCEL_ERROR;
154     }
155     if (!data.WriteString(uid)) {
156         HILOG_ERROR("fail write uid");
157         return ERR_APPEXECFWK_PARCEL_ERROR;
158     }
159     int error = SendTransactCmd(
160         IFormRender::Message::FORM_RENDER_RELEASE_RENDERER,
161         data,
162         reply,
163         option);
164     if (error != ERR_OK) {
165         HILOG_ERROR("SendRequest:%{public}d failed", error);
166         return error;
167     }
168     return ERR_OK;
169 }
170 
ReloadForm(const std::vector<FormJsInfo> && formJsInfos,const Want & want)171 int32_t FormRenderProxy::ReloadForm(const std::vector<FormJsInfo> &&formJsInfos, const Want &want)
172 {
173     MessageParcel data;
174     MessageParcel reply;
175     MessageOption option(MessageOption::TF_ASYNC);
176     if (!WriteInterfaceToken(data)) {
177         HILOG_ERROR("write interface token failed");
178         return ERR_APPEXECFWK_PARCEL_ERROR;
179     }
180 
181     int32_t error = WriteParcelableVector<FormJsInfo>(formJsInfos, data);
182     if (error != ERR_OK) {
183         HILOG_ERROR("fail WriteParcelableVector<FormJsInfo>");
184         return ERR_APPEXECFWK_PARCEL_ERROR;
185     }
186 
187     if (!data.WriteParcelable(&want)) {
188         HILOG_ERROR("write want failed");
189         return ERR_APPEXECFWK_PARCEL_ERROR;
190     }
191 
192     error = SendTransactCmd(
193         IFormRender::Message::FORM_RENDER_RELOAD_FORM,
194         data,
195         reply,
196         option);
197     if (error != ERR_OK) {
198         HILOG_ERROR("SendRequest:%{public}d failed", error);
199         return error;
200     }
201 
202     return ERR_OK;
203 }
204 
OnUnlock()205 int32_t FormRenderProxy::OnUnlock()
206 {
207     MessageParcel data;
208     MessageParcel reply;
209     MessageOption option(MessageOption::TF_ASYNC);
210     if (!WriteInterfaceToken(data)) {
211         HILOG_ERROR("write interface token failed");
212         return ERR_APPEXECFWK_PARCEL_ERROR;
213     }
214 
215     int32_t error = SendTransactCmd(
216         IFormRender::Message::FORM_RENDER_UNLOCKED,
217         data,
218         reply,
219         option);
220     if (error != ERR_OK) {
221         HILOG_ERROR("SendRequest:%{public}d failed", error);
222         return error;
223     }
224 
225     return ERR_OK;
226 }
227 
SetVisibleChange(const int64_t & formId,bool isVisible,const Want & want)228 int32_t FormRenderProxy::SetVisibleChange(const int64_t &formId, bool isVisible, const Want &want)
229 {
230     MessageParcel data;
231     MessageParcel reply;
232     MessageOption option(MessageOption::TF_ASYNC);
233     HILOG_ERROR("begin");
234 
235     if (!WriteInterfaceToken(data)) {
236         HILOG_ERROR("error to write interface token");
237         return ERR_APPEXECFWK_PARCEL_ERROR;
238     }
239 
240     if (!data.WriteInt64(formId)) {
241         HILOG_ERROR("write formId failed");
242         return ERR_APPEXECFWK_PARCEL_ERROR;
243     }
244     if (!data.WriteBool(isVisible)) {
245         HILOG_ERROR("write isVisible failed");
246         return ERR_APPEXECFWK_PARCEL_ERROR;
247     }
248 
249     if (!data.WriteParcelable(&want)) {
250         HILOG_ERROR("write want failed");
251         return ERR_APPEXECFWK_PARCEL_ERROR;
252     }
253 
254     int32_t error = SendTransactCmd(
255         IFormRender::Message::FORM_SET_VISIBLE_CHANGE, data, reply, option);
256     if (error != ERR_OK) {
257         HILOG_ERROR("SendRequest:%{public}d failed", error);
258         return error;
259     }
260     HILOG_ERROR("end");
261     return ERR_OK;
262 }
263 
SendTransactCmd(IFormRender::Message code,MessageParcel & data,MessageParcel & reply,MessageOption & option)264 int FormRenderProxy::SendTransactCmd(IFormRender::Message code, MessageParcel &data,
265                                      MessageParcel &reply, MessageOption &option)
266 {
267     sptr<IRemoteObject> remote = Remote();
268     if (!remote) {
269         HILOG_ERROR("error to get remote object, cmd:%{public}d", code);
270         return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
271     }
272     int32_t result = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
273     if (result != ERR_OK) {
274         HILOG_ERROR("error to SendRequest:%{public}d, cmd:%{public}d", result, code);
275         return result;
276     }
277     return ERR_OK;
278 }
279 
280 template<typename T>
WriteParcelableVector(const std::vector<T> & parcelableVector,MessageParcel & reply)281 int32_t FormRenderProxy::WriteParcelableVector(const std::vector<T> &parcelableVector, MessageParcel &reply)
282 {
283     if (!reply.WriteInt32(parcelableVector.size())) {
284         HILOG_ERROR("write ParcelableVector size failed");
285         return ERR_APPEXECFWK_PARCEL_ERROR;
286     }
287 
288     for (auto &parcelable : parcelableVector) {
289         if (!reply.WriteParcelable(&parcelable)) {
290             HILOG_ERROR("write ParcelableVector failed");
291             return ERR_APPEXECFWK_PARCEL_ERROR;
292         }
293     }
294     return ERR_OK;
295 }
296 
RecycleForm(const int64_t & formId,const Want & want)297 int32_t FormRenderProxy::RecycleForm(const int64_t &formId, const Want &want)
298 {
299     MessageParcel data;
300     MessageOption option(MessageOption::TF_ASYNC);
301     if (!WriteInterfaceToken(data)) {
302         HILOG_ERROR("write interface token failed");
303         return ERR_APPEXECFWK_PARCEL_ERROR;
304     }
305     if (!data.WriteInt64(formId)) {
306         HILOG_ERROR("write formId failed");
307         return ERR_APPEXECFWK_PARCEL_ERROR;
308     }
309     if (!data.WriteParcelable(&want)) {
310         HILOG_ERROR("write want failed");
311         return ERR_APPEXECFWK_PARCEL_ERROR;
312     }
313 
314     MessageParcel reply;
315     int32_t error = SendTransactCmd(
316         IFormRender::Message::FORM_RECYCLE_FORM,
317         data,
318         reply,
319         option);
320     if (error != ERR_OK) {
321         HILOG_ERROR("SendRequest:%{public}d failed", error);
322         return error;
323     }
324 
325     return ERR_OK;
326 }
327 
RecoverForm(const FormJsInfo & formJsInfo,const Want & want)328 int32_t FormRenderProxy::RecoverForm(const FormJsInfo &formJsInfo, const Want &want)
329 {
330     MessageParcel data;
331     MessageOption option(MessageOption::TF_ASYNC);
332     if (!WriteInterfaceToken(data)) {
333         HILOG_ERROR("write interface token failed");
334         return ERR_APPEXECFWK_PARCEL_ERROR;
335     }
336     if (!data.WriteParcelable(&formJsInfo)) {
337         HILOG_ERROR("fail write formJsInfo");
338         return ERR_APPEXECFWK_PARCEL_ERROR;
339     }
340     if (!data.WriteParcelable(&want)) {
341         HILOG_ERROR("write want failed");
342         return ERR_APPEXECFWK_PARCEL_ERROR;
343     }
344 
345     MessageParcel reply;
346     int32_t error = SendTransactCmd(
347         IFormRender::Message::FORM_RECOVER_FORM,
348         data,
349         reply,
350         option);
351     if (error != ERR_OK) {
352         HILOG_ERROR("SendRequest:%{public}d failed", error);
353         return error;
354     }
355 
356     return ERR_OK;
357 }
358 
RunCachedConfigurationUpdated()359 void FormRenderProxy::RunCachedConfigurationUpdated()
360 {
361     MessageParcel data;
362     MessageOption option(MessageOption::TF_ASYNC);
363     if (!WriteInterfaceToken(data)) {
364         HILOG_ERROR("write interface token failed");
365         return;
366     }
367     if (!Remote()) {
368         HILOG_ERROR("null remoteObj");
369         return;
370     }
371 
372     MessageParcel reply;
373     int32_t error = Remote()->SendRequest(
374         static_cast<uint32_t>(IFormRender::Message::FORM_RUN_CACHED_CONFIG),
375         data,
376         reply,
377         option);
378     if (error != ERR_OK) {
379         HILOG_ERROR("SendRequest:%{public}d failed", error);
380     }
381 }
382 
UpdateFormSize(const int64_t & formId,float width,float height,float borderWidth,const std::string & uid)383 int32_t FormRenderProxy::UpdateFormSize(const int64_t &formId, float width, float height, float borderWidth,
384     const std::string &uid)
385 {
386     MessageParcel data;
387     MessageOption option(MessageOption::TF_ASYNC);
388     if (!WriteInterfaceToken(data)) {
389         HILOG_ERROR("write interface token failed");
390         return ERR_APPEXECFWK_PARCEL_ERROR;
391     }
392     if (!data.WriteInt64(formId)) {
393         HILOG_ERROR("write formId failed");
394         return ERR_APPEXECFWK_PARCEL_ERROR;
395     }
396     if (!data.WriteFloat(width)) {
397         HILOG_ERROR("fail write width");
398         return ERR_APPEXECFWK_PARCEL_ERROR;
399     }
400     if (!data.WriteFloat(height)) {
401         HILOG_ERROR("fail write height");
402         return ERR_APPEXECFWK_PARCEL_ERROR;
403     }
404     if (!data.WriteFloat(borderWidth)) {
405         HILOG_ERROR("fail write borderWidth");
406         return ERR_APPEXECFWK_PARCEL_ERROR;
407     }
408     if (!data.WriteString(uid)) {
409         HILOG_ERROR("fail write uid");
410         return ERR_APPEXECFWK_PARCEL_ERROR;
411     }
412     MessageParcel reply;
413     int32_t error = SendTransactCmd(
414         IFormRender::Message::FORM_UPDATE_FORM_SIZE,
415         data,
416         reply,
417         option);
418     if (error != ERR_OK) {
419         HILOG_ERROR("SendRequest:%{public}d failed", error);
420         return error;
421     }
422 
423     return ERR_OK;
424 }
425 } // namespace AppExecFwk
426 } // namespace OHOS
427