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_stub.h"
16 #include "appexecfwk_errors.h"
17 #include "app_scheduler_interface.h"
18 #include "errors.h"
19 #include "fms_log_wrapper.h"
20 #include "form_mgr_errors.h"
21 #include "ipc_skeleton.h"
22 #include "ipc_types.h"
23 #include "iremote_object.h"
24 #include "xcollie/watchdog.h"
25 #include "xcollie/xcollie.h"
26 #include "xcollie/xcollie_define.h"
27 
28 namespace OHOS {
29 namespace AppExecFwk {
30 namespace {
31     constexpr int32_t MAX_ALLOW_SIZE = 8 * 1024;
32     constexpr int32_t FORM_RENDER_API_TIME_OUT = 30;
33 }
34 
FormRenderStub()35 FormRenderStub::FormRenderStub()
36 {}
37 
~FormRenderStub()38 FormRenderStub::~FormRenderStub()
39 {}
40 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)41 int FormRenderStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
42 {
43     HILOG_DEBUG("FormRenderStub::OnReceived,code = %{public}u,flags= %{public}d", code, option.GetFlags());
44     std::u16string descriptor = FormRenderStub::GetDescriptor();
45     std::u16string remoteDescriptor = data.ReadInterfaceToken();
46     if (descriptor != remoteDescriptor) {
47         HILOG_ERROR("localDescriptor not equal to remote");
48         return ERR_APPEXECFWK_FORM_INVALID_PARAM;
49     }
50 
51     switch (code) {
52         case static_cast<uint32_t>(IFormRender::Message::FORM_RENDER_RENDER_FORM):
53             return HandleRenderForm(data, reply);
54         case static_cast<uint32_t>(IFormRender::Message::FORM_RENDER_STOP_RENDERING_FORM):
55             return HandleStopRenderingForm(data, reply);
56         case static_cast<uint32_t>(IFormRender::Message::FORM_RENDER_FORM_HOST_DIED):
57             return HandleCleanFormHost(data, reply);
58         case static_cast<uint32_t>(IFormRender::Message::FORM_RENDER_RELOAD_FORM):
59             return HandleReloadForm(data, reply);
60         case static_cast<uint32_t>(IFormRender::Message::FORM_RENDER_RELEASE_RENDERER):
61             return HandleReleaseRenderer(data, reply);
62         case static_cast<uint32_t>(IFormRender::Message::FORM_RENDER_UNLOCKED):
63             return HandleOnUnlock(data, reply);
64         case static_cast<uint32_t>(IFormRender::Message::FORM_RECYCLE_FORM):
65             return HandleRecycleForm(data, reply);
66         case static_cast<uint32_t>(IFormRender::Message::FORM_RECOVER_FORM):
67             return HandleRecoverForm(data, reply);
68         case static_cast<uint32_t>(IFormRender::Message::FORM_RUN_CACHED_CONFIG):{
69             int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_RunCachedConfigurationUpdated",
70                 FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
71             RunCachedConfigurationUpdated();
72             HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
73             return ERR_OK;
74         }
75         case static_cast<uint32_t>(IFormRender::Message::FORM_SET_VISIBLE_CHANGE):
76             return HandleSetVisibleChange(data, reply);
77         case static_cast<uint32_t>(IFormRender::Message::FORM_UPDATE_FORM_SIZE):
78             return HandleUpdateFormSize(data, reply);
79         default:
80             return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
81     }
82 }
83 
HandleRenderForm(MessageParcel & data,MessageParcel & reply)84 int FormRenderStub::HandleRenderForm(MessageParcel &data, MessageParcel &reply)
85 {
86     std::unique_ptr<FormJsInfo> formJsInfo(data.ReadParcelable<FormJsInfo>());
87     if (!formJsInfo) {
88         HILOG_ERROR("error to ReadParcelable<formJsInfo>");
89         return ERR_APPEXECFWK_PARCEL_ERROR;
90     }
91     std::unique_ptr<Want> want(data.ReadParcelable<Want>());
92     if (!want) {
93         HILOG_ERROR("error to ReadParcelable<Want>");
94         return ERR_APPEXECFWK_PARCEL_ERROR;
95     }
96 
97     sptr<IRemoteObject> client = data.ReadRemoteObject();
98     if (client == nullptr) {
99         HILOG_ERROR("error to get remote object");
100         return ERR_APPEXECFWK_PARCEL_ERROR;
101     }
102 
103     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_RenderForm",
104         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
105     int32_t result = RenderForm(*formJsInfo, *want, client);
106     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
107     reply.WriteInt32(result);
108     return result;
109 }
110 
HandleStopRenderingForm(MessageParcel & data,MessageParcel & reply)111 int FormRenderStub::HandleStopRenderingForm(MessageParcel &data, MessageParcel &reply)
112 {
113     std::unique_ptr<FormJsInfo> formJsInfo(data.ReadParcelable<FormJsInfo>());
114     if (!formJsInfo) {
115         HILOG_ERROR("ReadParcelable<formJsInfo> fail");
116         return ERR_APPEXECFWK_PARCEL_ERROR;
117     }
118     std::unique_ptr<Want> want(data.ReadParcelable<Want>());
119     if (!want) {
120         HILOG_ERROR("ReadParcelable<Want> fail");
121         return ERR_APPEXECFWK_PARCEL_ERROR;
122     }
123 
124     sptr<IRemoteObject> client = data.ReadRemoteObject();
125     if (client == nullptr) {
126         HILOG_ERROR("get remote object failed");
127         return ERR_APPEXECFWK_PARCEL_ERROR;
128     }
129 
130     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_StopRenderingForm",
131         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
132     int32_t result = StopRenderingForm(*formJsInfo, *want, client);
133     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
134     reply.WriteInt32(result);
135     return result;
136 }
137 
HandleCleanFormHost(MessageParcel & data,MessageParcel & reply)138 int FormRenderStub::HandleCleanFormHost(MessageParcel &data, MessageParcel &reply)
139 {
140     sptr<IRemoteObject> hostToken = data.ReadRemoteObject();
141     if (hostToken == nullptr) {
142         HILOG_ERROR("null hostToken");
143         return ERR_APPEXECFWK_PARCEL_ERROR;
144     }
145 
146     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_CleanFormHost",
147         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
148     int32_t result = CleanFormHost(hostToken);
149     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
150     reply.WriteInt32(result);
151     return result;
152 }
153 
HandleReleaseRenderer(MessageParcel & data,MessageParcel & reply)154 int32_t FormRenderStub::HandleReleaseRenderer(MessageParcel &data, MessageParcel &reply)
155 {
156     int64_t formId = data.ReadInt64();
157     std::string compId = data.ReadString();
158     std::string uid = data.ReadString();
159     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_ReleaseRenderer",
160         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
161     int32_t result = ReleaseRenderer(formId, compId, uid);
162     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
163     reply.WriteInt32(result);
164     return result;
165 }
166 
HandleReloadForm(MessageParcel & data,MessageParcel & reply)167 int FormRenderStub::HandleReloadForm(MessageParcel &data, MessageParcel &reply)
168 {
169     std::vector<FormJsInfo> formJsInfos;
170     int32_t result = GetParcelableInfos(data, formJsInfos);
171     if (result != ERR_OK) {
172         HILOG_ERROR("fail GetParcelableInfos<FormJsInfo>");
173         return result;
174     }
175 
176     std::unique_ptr<Want> want(data.ReadParcelable<Want>());
177     if (!want) {
178         HILOG_ERROR("ReadParcelable<Want> failed");
179         return ERR_APPEXECFWK_PARCEL_ERROR;
180     }
181 
182     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_ReloadForm",
183         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
184     result = ReloadForm(std::move(formJsInfos), *want);
185     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
186     reply.WriteInt32(result);
187     return result;
188 }
189 
HandleOnUnlock(MessageParcel & data,MessageParcel & reply)190 int32_t FormRenderStub::HandleOnUnlock(MessageParcel &data, MessageParcel &reply)
191 {
192     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_OnUnlock",
193         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
194     int32_t result = OnUnlock();
195     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
196     reply.WriteInt32(result);
197     return result;
198 }
199 
HandleSetVisibleChange(MessageParcel & data,MessageParcel & reply)200 int32_t FormRenderStub::HandleSetVisibleChange(MessageParcel &data, MessageParcel &reply)
201 {
202     HILOG_ERROR("begin");
203     int64_t formId = data.ReadInt64();
204     bool isVisible = data.ReadBool();
205     std::unique_ptr<Want> want(data.ReadParcelable<Want>());
206     if (!want) {
207         HILOG_ERROR("error to ReadParcelable<Want>");
208         return ERR_APPEXECFWK_PARCEL_ERROR;
209     }
210     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_SetVisibleChange",
211         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
212     int32_t result = SetVisibleChange(formId, isVisible, *want);
213     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
214     reply.WriteInt32(result);
215     HILOG_ERROR("end");
216     return result;
217 }
218 
219 template<typename T>
GetParcelableInfos(MessageParcel & reply,std::vector<T> & parcelableInfos)220 int32_t FormRenderStub::GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos)
221 {
222     int32_t infoSize = reply.ReadInt32();
223     if (infoSize < 0 || infoSize > MAX_ALLOW_SIZE) {
224         HILOG_ERROR("invalid size:%{public}d", infoSize);
225         return ERR_APPEXECFWK_PARCEL_ERROR;
226     }
227 
228     for (int32_t i = 0; i < infoSize; i++) {
229         std::unique_ptr<T> info(reply.ReadParcelable<T>());
230         if (!info) {
231             HILOG_ERROR("Read Parcelable infos error");
232             return ERR_APPEXECFWK_PARCEL_ERROR;
233         }
234         parcelableInfos.emplace_back(*info);
235     }
236     return ERR_OK;
237 }
238 
HandleRecycleForm(MessageParcel & data,MessageParcel & reply)239 int32_t FormRenderStub::HandleRecycleForm(MessageParcel &data, MessageParcel &reply)
240 {
241     int64_t formId = data.ReadInt64();
242     std::unique_ptr<Want> want(data.ReadParcelable<Want>());
243     if (!want) {
244         HILOG_ERROR("error to ReadParcelable<Want>");
245         return ERR_APPEXECFWK_PARCEL_ERROR;
246     }
247     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_RecycleForm",
248         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
249     int32_t result = RecycleForm(formId, *want);
250     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
251     reply.WriteInt32(result);
252     return result;
253 }
254 
HandleRecoverForm(MessageParcel & data,MessageParcel & reply)255 int32_t FormRenderStub::HandleRecoverForm(MessageParcel &data, MessageParcel &reply)
256 {
257     std::unique_ptr<FormJsInfo> formJsInfo(data.ReadParcelable<FormJsInfo>());
258     if (!formJsInfo) {
259         HILOG_ERROR("read FormJsInfo error");
260         return ERR_APPEXECFWK_PARCEL_ERROR;
261     }
262     std::unique_ptr<Want> want(data.ReadParcelable<Want>());
263     if (!want) {
264         HILOG_ERROR("read want error");
265         return ERR_APPEXECFWK_PARCEL_ERROR;
266     }
267     int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("FRS_RecoverForm",
268         FORM_RENDER_API_TIME_OUT, nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_LOG);
269     int32_t result = RecoverForm(*formJsInfo, *want);
270     HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
271     reply.WriteInt32(result);
272     return result;
273 }
274 
HandleUpdateFormSize(MessageParcel & data,MessageParcel & reply)275 int32_t FormRenderStub::HandleUpdateFormSize(MessageParcel &data, MessageParcel &reply)
276 {
277     int64_t formId = data.ReadInt64();
278     float width = data.ReadFloat();
279     float height = data.ReadFloat();
280     float borderWidth = data.ReadFloat();
281     std::string uid = data.ReadString();
282     int32_t result = UpdateFormSize(formId, width, height, borderWidth, uid);
283     reply.WriteInt32(result);
284     return result;
285 }
286 }  // namespace AppExecFwk
287 }  // namespace OHOS
288