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