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_host_proxy.h"
17 
18 #include "appexecfwk_errors.h"
19 #include "string_ex.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24     static constexpr int32_t MAX_ALLOW_SIZE = 8 * 1024;
25 }
OnAcquired(const FormJsInfo & formInfo,const sptr<IRemoteObject> & token)26 void FormHostProxy::OnAcquired(const FormJsInfo &formInfo, const sptr<IRemoteObject> &token)
27 {
28     int error;
29     MessageParcel data;
30     MessageParcel reply;
31     MessageOption option;
32 
33     if (!WriteInterfaceToken(data)) {
34         HILOG_ERROR("write interface token failed");
35     }
36 
37     if (!data.WriteParcelable(&formInfo)) {
38         HILOG_ERROR("write formInfo failed");
39     }
40 
41     if (token != nullptr) {
42         if (!data.WriteBool(true) || !data.WriteRemoteObject(token)) {
43             HILOG_ERROR("flag or token write failed");
44         }
45     } else {
46         if (!data.WriteBool(false)) {
47             HILOG_ERROR("flag write failed");
48         }
49     }
50 
51     error = SendTransactCmd(
52         IFormHost::Message::FORM_HOST_ON_ACQUIRED,
53         data,
54         reply,
55         option);
56     if (error != ERR_OK) {
57         HILOG_ERROR("SendRequest:%{public}d failed", error);
58     }
59 }
60 
61 
62 /**
63 * @brief Form is updated.
64 * @param bundleName Provider ability bundleName.
65 */
OnUpdate(const FormJsInfo & formInfo)66 void FormHostProxy::OnUpdate(const FormJsInfo &formInfo)
67 {
68     int error;
69     MessageParcel data;
70     MessageParcel reply;
71     MessageOption option;
72 
73     if (!WriteInterfaceToken(data)) {
74         HILOG_ERROR("write interface token failed");
75     }
76 
77     if (!data.WriteParcelable(&formInfo)) {
78         HILOG_ERROR("write formInfo failed");
79     }
80 
81     error = SendTransactCmd(IFormHost::Message::FORM_HOST_ON_UPDATE, data, reply, option);
82     if (error != ERR_OK) {
83         HILOG_ERROR("SendRequest:%{public}d failed", error);
84     }
85 }
86 
87 
88 /**
89  * @brief Form provider is uninstalled
90  * @param formIds The Id list of the forms.
91  */
OnUninstall(const std::vector<int64_t> & formIds)92 void  FormHostProxy::OnUninstall(const std::vector<int64_t> &formIds)
93 {
94     int error;
95     MessageParcel data;
96     MessageParcel reply;
97     MessageOption option;
98 
99     if (!WriteInterfaceToken(data)) {
100         HILOG_ERROR("write interface token failed");
101     }
102 
103     if (!data.WriteInt64Vector(formIds)) {
104         HILOG_ERROR("write formIds failed");
105     }
106 
107     error = SendTransactCmd(
108         IFormHost::Message::FORM_HOST_ON_UNINSTALL,
109         data,
110         reply,
111         option);
112     if (error != ERR_OK) {
113         HILOG_ERROR("SendRequest:%{public}d failed", error);
114     }
115 }
116 
117 /**
118  * @brief Form provider is acquire state
119  * @param state The form state.
120  * @param want The form want.
121  */
OnAcquireState(FormState state,const AAFwk::Want & want)122 void FormHostProxy::OnAcquireState(FormState state, const AAFwk::Want &want)
123 {
124     int error;
125     MessageParcel data;
126     MessageParcel reply;
127     MessageOption option;
128 
129     if (!WriteInterfaceToken(data)) {
130         HILOG_ERROR("write interface token failed");
131         return;
132     }
133 
134     if (!data.WriteInt32((int32_t) state)) {
135         HILOG_ERROR("write state failed");
136         return;
137     }
138 
139     if (!data.WriteParcelable(&want)) {
140         HILOG_ERROR("write want failed");
141         return;
142     }
143 
144     error = SendTransactCmd(
145         IFormHost::Message::FORM_HOST_ON_ACQUIRE_FORM_STATE,
146         data,
147         reply,
148         option);
149     if (error != ERR_OK) {
150         HILOG_ERROR("SendRequest:%{public}d failed", error);
151     }
152 }
153 
OnAcquireDataResponse(const AAFwk::WantParams & wantParams,int64_t requestCode)154 void FormHostProxy::OnAcquireDataResponse(const AAFwk::WantParams &wantParams, int64_t requestCode)
155 {
156     MessageParcel data;
157     MessageParcel reply;
158     MessageOption option;
159 
160     if (!WriteInterfaceToken(data)) {
161         HILOG_ERROR("write interface token failed");
162         return;
163     }
164 
165     if (!data.WriteParcelable(&wantParams)) {
166         HILOG_ERROR("fail write form wantParams");
167         return;
168     }
169     if (!data.WriteInt64(requestCode)) {
170         HILOG_ERROR("write formRequestCode failed");
171         return;
172     }
173     int error;
174 
175     error = SendTransactCmd(
176         IFormHost::Message::FORM_HOST_ON_ACQUIRE_FORM_DATA,
177         data,
178         reply,
179         option);
180     if (error != ERR_OK) {
181         HILOG_ERROR("SendRequest:%{public}d failed", error);
182     }
183 }
184 
185 
186 template<typename T>
GetParcelableInfos(MessageParcel & reply,std::vector<T> & parcelableInfos)187 int  FormHostProxy::GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos)
188 {
189     int32_t infoSize = reply.ReadInt32();
190     if (infoSize < 0 || infoSize > MAX_ALLOW_SIZE) {
191         HILOG_ERROR("invalid size:%{public}d", infoSize);
192         return ERR_APPEXECFWK_PARCEL_ERROR;
193     }
194     for (int32_t i = 0; i < infoSize; i++) {
195         std::unique_ptr<T> info(reply.ReadParcelable<T>());
196         if (!info) {
197             HILOG_ERROR("read Parcelable infos failed");
198             return ERR_APPEXECFWK_PARCEL_ERROR;
199         }
200         parcelableInfos.emplace_back(*info);
201     }
202     HILOG_INFO("get success");
203     return ERR_OK;
204 }
205 
WriteInterfaceToken(MessageParcel & data)206 bool  FormHostProxy::WriteInterfaceToken(MessageParcel &data)
207 {
208     if (!data.WriteInterfaceToken(FormHostProxy::GetDescriptor())) {
209         HILOG_ERROR("write interface token failed");
210         return false;
211     }
212     return true;
213 }
214 
OnShareFormResponse(int64_t requestCode,int32_t result)215 void FormHostProxy::OnShareFormResponse(int64_t requestCode, int32_t result)
216 {
217     MessageParcel data;
218     MessageParcel reply;
219     MessageOption option;
220 
221     if (!WriteInterfaceToken(data)) {
222         HILOG_ERROR("write interface token failed");
223         return;
224     }
225 
226     if (!data.WriteInt64(requestCode)) {
227         HILOG_ERROR("write requestCode failed");
228         return;
229     }
230 
231     if (!data.WriteInt32(result)) {
232         HILOG_ERROR("write result failed");
233         return;
234     }
235 
236     int32_t error = SendTransactCmd(
237         IFormHost::Message::FORM_HOST_ON_SHARE_FORM_RESPONSE,
238         data,
239         reply,
240         option);
241     if (error != ERR_OK) {
242         HILOG_ERROR("SendRequest:%{public}d failed", error);
243     }
244 }
245 
OnError(int32_t errorCode,const std::string & errorMsg)246 void FormHostProxy::OnError(int32_t errorCode, const std::string &errorMsg)
247 {
248     MessageParcel data;
249     MessageParcel reply;
250     MessageOption option(MessageOption::TF_ASYNC);
251 
252     if (!WriteInterfaceToken(data)) {
253         HILOG_ERROR("write interface token failed");
254         return;
255     }
256 
257     if (!data.WriteInt32(errorCode)) {
258         HILOG_ERROR("write ErrorCode failed");
259         return;
260     }
261 
262     if (!data.WriteString16(Str8ToStr16(errorMsg))) {
263         HILOG_ERROR("fail write errorMsg");
264         return;
265     }
266 
267     int error = SendTransactCmd(
268         IFormHost::Message::FORM_HOST_ON_ERROR,
269         data, reply, option);
270     if (error != ERR_OK) {
271         HILOG_ERROR("SendRequest:%{public}d failed", error);
272     }
273 }
274 
OnError(int32_t errorCode,const std::string & errorMsg,std::vector<int64_t> & formIds)275 void FormHostProxy::OnError(int32_t errorCode, const std::string &errorMsg, std::vector<int64_t> &formIds)
276 {
277     MessageParcel data;
278     MessageParcel reply;
279     MessageOption option(MessageOption::TF_ASYNC);
280 
281     if (!WriteInterfaceToken(data)) {
282         HILOG_ERROR("write interface token failed");
283         return;
284     }
285 
286     if (!data.WriteInt32(errorCode)) {
287         HILOG_ERROR("write ErrorCode failed");
288         return;
289     }
290 
291     if (!data.WriteString16(Str8ToStr16(errorMsg))) {
292         HILOG_ERROR("fail write errorMsg");
293         return;
294     }
295 
296     if (!data.WriteInt64Vector(formIds)) {
297         HILOG_ERROR("write formIds failed");
298     }
299 
300     int error = SendTransactCmd(
301         IFormHost::Message::FORM_HOST_ON_ERROR_FORMS,
302         data, reply, option);
303     if (error != ERR_OK) {
304         HILOG_ERROR("SendRequest:%{public}d failed", error);
305     }
306 }
307 
308 
SendTransactCmd(IFormHost::Message code,MessageParcel & data,MessageParcel & reply,MessageOption & option)309 int FormHostProxy::SendTransactCmd(IFormHost::Message code, MessageParcel &data,
310     MessageParcel &reply, MessageOption &option)
311 {
312     sptr<IRemoteObject> remote = Remote();
313     if (!remote) {
314         HILOG_ERROR("get remoteObject failed, cmd:%{public}d", code);
315         return ERR_APPEXECFWK_SERVICE_NOT_CONNECTED;
316     }
317     int32_t result = remote->SendRequest(static_cast<uint32_t>(code), data, reply, option);
318     if (result != ERR_OK) {
319         HILOG_ERROR("SendRequest failed:%{public}d,cmd:%{public}d", result, code);
320         return result;
321     }
322     return ERR_OK;
323 }
324 
OnRecycleForm(const int64_t & formId)325 void FormHostProxy::OnRecycleForm(const int64_t &formId)
326 {
327     MessageParcel data;
328     MessageOption option(MessageOption::TF_ASYNC);
329 
330     if (!WriteInterfaceToken(data)) {
331         HILOG_ERROR("write interface token failed");
332         return;
333     }
334 
335     if (!data.WriteInt64(formId)) {
336         HILOG_ERROR("write formId failed");
337         return;
338     }
339 
340     MessageParcel reply;
341     int error = SendTransactCmd(
342         IFormHost::Message::FORM_HOST_ON_RECYCLE_FORM,
343         data,
344         reply,
345         option);
346     if (error != ERR_OK) {
347         HILOG_ERROR("SendRequest:%{public}d failed", error);
348     }
349 }
350 
OnEnableForm(const std::vector<int64_t> & formIds,const bool enable)351 void FormHostProxy::OnEnableForm(const std::vector<int64_t> &formIds, const bool enable)
352 {
353     MessageParcel data;
354     MessageOption option(MessageOption::TF_ASYNC);
355 
356     if (!WriteInterfaceToken(data)) {
357         HILOG_ERROR("write interface token failed");
358         return;
359     }
360 
361     if (!data.WriteInt64Vector(formIds)) {
362         HILOG_ERROR("fail write formIds");
363         return;
364     }
365 
366     if (!data.WriteBool(enable)) {
367         HILOG_ERROR("write formId failed");
368         return;
369     }
370 
371     MessageParcel reply;
372     int error = SendTransactCmd(
373         IFormHost::Message::FORM_HOST_ON_ENABLE_FORM,
374         data, reply, option);
375     if (error != ERR_OK) {
376         HILOG_ERROR("SendRequest:%{public}d failed", error);
377     }
378 }
379 }  // namespace AppExecFwk
380 }  // namespace OHOS
381