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