1 /*
2 * Copyright (c) 2021 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 <thread>
17 #include "appexecfwk_errors.h"
18 #include "app_log_wrapper.h"
19 #include "form_errors.h"
20 #include "form_mgr.h"
21 #include "if_system_ability_manager.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "string_ex.h"
25 #include "system_ability_definition.h"
26
27 namespace OHOS {
28 namespace AppExecFwk {
FormMgr()29 FormMgr::FormMgr(){}
~FormMgr()30 FormMgr::~FormMgr()
31 {
32 if (remoteProxy_ != nullptr) {
33 auto remoteObject = remoteProxy_->AsObject();
34 if (remoteObject != nullptr) {
35 remoteObject->RemoveDeathRecipient(deathRecipient_);
36 }
37 }
38 }
39 /**
40 * @brief Add form with want, send want to form manager service.
41 * @param formId The Id of the forms to add.
42 * @param want The want of the form to add.
43 * @param callerToken Caller ability token.
44 * @param formInfo Form info.
45 * @return Returns ERR_OK on success, others on failure.
46 */
AddForm(const int64_t formId,const Want & want,const sptr<IRemoteObject> & callerToken,FormJsInfo & formInfo)47 int FormMgr::AddForm(
48 const int64_t formId,
49 const Want &want,
50 const sptr<IRemoteObject> &callerToken,
51 FormJsInfo &formInfo)
52 {
53 APP_LOGI("%{public}s called.", __func__);
54
55 int errCode = Connect();
56 if (errCode != ERR_OK) {
57 return errCode;
58 }
59
60 return remoteProxy_->AddForm(formId, want, callerToken, formInfo);
61 }
62
63 /**
64 * @brief Delete forms with formIds, send formIds to form manager service.
65 * @param formId The Id of the forms to delete.
66 * @param callerToken Caller ability token.
67 * @return Returns ERR_OK on success, others on failure.
68 */
DeleteForm(const int64_t formId,const sptr<IRemoteObject> & callerToken)69 int FormMgr::DeleteForm(const int64_t formId, const sptr<IRemoteObject> &callerToken)
70 {
71 APP_LOGI("%{public}s called.", __func__);
72
73 int errCode = Connect();
74 if (errCode != ERR_OK) {
75 return errCode;
76 }
77
78 return remoteProxy_->DeleteForm(formId, callerToken);
79 }
80
81 /**
82 * @brief Release forms with formIds, send formIds to form manager service.
83 * @param formId The Id of the forms to release.
84 * @param callerToken Caller ability token.
85 * @param delCache Delete Cache or not.
86 * @return Returns ERR_OK on success, others on failure.
87 */
ReleaseForm(const int64_t formId,const sptr<IRemoteObject> & callerToken,const bool delCache)88 int FormMgr::ReleaseForm(const int64_t formId, const sptr<IRemoteObject> &callerToken, const bool delCache)
89 {
90 APP_LOGI("%{public}s called.", __func__);
91
92 int errCode = Connect();
93 if (errCode != ERR_OK) {
94 return errCode;
95 }
96
97 return remoteProxy_->ReleaseForm(formId, callerToken, delCache);
98 }
99
100 /**
101 * @brief Update form with formId, send formId to form manager service.
102 * @param formId The Id of the form to update.
103 * @param bundleName Provider ability bundleName.
104 * @param formBindingData Form binding data.
105 * @return Returns ERR_OK on success, others on failure.
106 */
UpdateForm(const int64_t formId,const std::string & bundleName,const FormProviderData & formBindingData)107 int FormMgr::UpdateForm(const int64_t formId, const std::string &bundleName, const FormProviderData &formBindingData)
108 {
109 APP_LOGI("%{public}s called.", __func__);
110
111 int errCode = Connect();
112 if (errCode != ERR_OK) {
113 return errCode;
114 }
115
116 // update form
117 return remoteProxy_->UpdateForm(formId, bundleName, formBindingData);
118 }
119
120 /**
121 * @brief Notify the form service that the form user's lifecycle is updated.
122 *
123 * This should be called when form user request form.
124 *
125 * @param formId Indicates the unique id of form.
126 * @param callerToken Indicates the callback remote object of specified form user.
127 * @param want information passed to supplier.
128 * @return Returns true if execute success, false otherwise.
129 */
RequestForm(const int64_t formId,const sptr<IRemoteObject> & callerToken,const Want & want)130 int FormMgr::RequestForm(const int64_t formId, const sptr<IRemoteObject> &callerToken, const Want &want)
131 {
132 APP_LOGI("%{public}s called.", __func__);
133
134 int errCode = Connect();
135 if (errCode != ERR_OK) {
136 return errCode;
137 }
138
139 return remoteProxy_->RequestForm(formId, callerToken, want);
140 }
141
142 /**
143 * @brief Form visible/invisible notify, send formIds to form manager service.
144 * @param formIds The Id list of the forms to notify.
145 * @param callerToken Caller ability token.
146 * @param formVisibleType The form visible type, including FORM_VISIBLE and FORM_INVISIBLE.
147 * @return Returns ERR_OK on success, others on failure.
148 */
NotifyWhetherVisibleForms(const std::vector<int64_t> & formIds,const sptr<IRemoteObject> & callerToken,const int32_t formVisibleType)149 int FormMgr::NotifyWhetherVisibleForms(
150 const std::vector<int64_t> &formIds,
151 const sptr<IRemoteObject> &callerToken,
152 const int32_t formVisibleType)
153 {
154 int errCode = Connect();
155 if (errCode != ERR_OK) {
156 return errCode;
157 }
158
159 return remoteProxy_->NotifyWhetherVisibleForms(formIds, callerToken, formVisibleType);
160 }
161
162 /**
163 * @brief temp form to normal form.
164 * @param formId The Id of the form.
165 * @param callerToken Caller ability token.
166 * @return None.
167 */
CastTempForm(const int64_t formId,const sptr<IRemoteObject> & callerToken)168 int FormMgr::CastTempForm(const int64_t formId, const sptr<IRemoteObject> &callerToken)
169 {
170 APP_LOGI("%{public}s called.", __func__);
171
172 int errCode = Connect();
173 if (errCode != ERR_OK) {
174 return errCode;
175 }
176
177 return remoteProxy_->CastTempForm(formId, callerToken);
178 }
179
180 /**
181 * @brief Dump all of form storage infos.
182 * @param formInfos All of form storage infos.
183 * @return Returns ERR_OK on success, others on failure.
184 */
DumpStorageFormInfos(std::string & formInfos)185 int FormMgr::DumpStorageFormInfos(std::string &formInfos)
186 {
187 int errCode = Connect();
188 if (errCode != ERR_OK) {
189 return errCode;
190 }
191
192 return remoteProxy_->DumpStorageFormInfos(formInfos);
193 }
194 /**
195 * @brief Dump form info by a bundle name.
196 * @param bundleName The bundle name of form provider.
197 * @param formInfos Form infos.
198 * @return Returns ERR_OK on success, others on failure.
199 */
DumpFormInfoByBundleName(const std::string bundleName,std::string & formInfos)200 int FormMgr::DumpFormInfoByBundleName(const std::string bundleName, std::string &formInfos)
201 {
202 int errCode = Connect();
203 if (errCode != ERR_OK) {
204 return errCode;
205 }
206
207 return remoteProxy_->DumpFormInfoByBundleName(bundleName, formInfos);
208 }
209 /**
210 * @brief Dump form info by a bundle name.
211 * @param formId The id of the form.
212 * @param formInfo Form info.
213 * @return Returns ERR_OK on success, others on failure.
214 */
DumpFormInfoByFormId(const std::int64_t formId,std::string & formInfo)215 int FormMgr::DumpFormInfoByFormId(const std::int64_t formId, std::string &formInfo)
216 {
217 int errCode = Connect();
218 if (errCode != ERR_OK) {
219 return errCode;
220 }
221
222 return remoteProxy_->DumpFormInfoByFormId(formId, formInfo);
223 }
224 /**
225 * @brief Process js message event.
226 * @param formId Indicates the unique id of form.
227 * @param want information passed to supplier.
228 * @param callerToken Caller ability token.
229 * @return Returns true if execute success, false otherwise.
230 */
MessageEvent(const int64_t formId,const Want & want,const sptr<IRemoteObject> & callerToken)231 int FormMgr::MessageEvent(const int64_t formId, const Want &want, const sptr<IRemoteObject> &callerToken)
232 {
233 int errCode = Connect();
234 if (errCode != ERR_OK) {
235 return errCode;
236 }
237
238 return remoteProxy_->MessageEvent(formId, want, callerToken);
239 }
240
241 /**
242 * @brief Set Next Refresh Time.
243 * @param formId The id of the form.
244 * @param bundleName The bundle name of form provider.
245 * @param nextTime Next refresh time.
246 * @return Returns ERR_OK on success, others on failure.
247 */
SetNextRefreshTime(const int64_t formId,const int64_t nextTime)248 int FormMgr::SetNextRefreshTime(const int64_t formId, const int64_t nextTime)
249 {
250 int errCode = Connect();
251 if (errCode != ERR_OK) {
252 return errCode;
253 }
254
255 return remoteProxy_->SetNextRefreshTime(formId, nextTime);
256 }
257
258 /**
259 * @brief Lifecycle Update.
260 * @param formIds The id of the forms.
261 * @param callerToken Host client.
262 * @param updateType Next refresh time.
263 * @return Returns ERR_OK on success, others on failure.
264 */
LifecycleUpdate(const std::vector<int64_t> & formIds,const sptr<IRemoteObject> & callerToken,const int32_t updateType)265 int FormMgr::LifecycleUpdate(
266 const std::vector<int64_t> &formIds,
267 const sptr<IRemoteObject> &callerToken,
268 const int32_t updateType)
269 {
270 int errCode = Connect();
271 if (errCode != ERR_OK) {
272 return errCode;
273 }
274
275 return remoteProxy_->LifecycleUpdate(formIds, callerToken, updateType);
276 }
277 /**
278 * @brief Get fms recoverStatus.
279 *
280 * @return The current recover status.
281 */
GetRecoverStatus()282 int FormMgr::GetRecoverStatus()
283 {
284 APP_LOGI("%{public}s called.", __func__);
285
286 return recoverStatus_;
287 }
288
289 /**
290 * @brief Set fms recoverStatus.
291 *
292 * @param recoverStatus The recover status.
293 */
SetRecoverStatus(int recoverStatus)294 void FormMgr::SetRecoverStatus(int recoverStatus)
295 {
296 APP_LOGI("%{public}s called.", __func__);
297
298 recoverStatus_ = recoverStatus;
299 }
300
301 /**
302 * @brief Get the error message content.
303 *
304 * @param errCode Error code.
305 * @return Message content.
306 */
GetErrorMessage(int errCode)307 std::string FormMgr::GetErrorMessage(int errCode)
308 {
309 return FormErrors::GetInstance().GetErrorMessage(errCode);
310 }
311
312 /**
313 * @brief Register death callback.
314 *
315 * @param deathCallback Death callback.
316 */
RegisterDeathCallback(const std::shared_ptr<FormCallbackInterface> & formDeathCallback)317 void FormMgr::RegisterDeathCallback(const std::shared_ptr<FormCallbackInterface> &formDeathCallback)
318 {
319 APP_LOGI("%{public}s called.", __func__);
320
321 if (formDeathCallback == nullptr) {
322 APP_LOGE("%{public}s error, form death callback is nullptr.", __func__);
323 return;
324 }
325
326 formDeathCallbacks_.emplace_back(formDeathCallback);
327 }
328
329 /**
330 * @brief UnRegister death callback.
331 *
332 * @param deathCallback Death callback.
333 */
UnRegisterDeathCallback(const std::shared_ptr<FormCallbackInterface> & formDeathCallback)334 void FormMgr::UnRegisterDeathCallback(const std::shared_ptr<FormCallbackInterface> &formDeathCallback)
335 {
336 APP_LOGI("%{public}s called.", __func__);
337
338 if (formDeathCallback == nullptr) {
339 APP_LOGE("%{public}s error, form death callback is nullptr.", __func__);
340 return;
341 }
342
343 // Remove the specified death callback in the vector of death callback
344 auto iter = std::find(formDeathCallbacks_.begin(), formDeathCallbacks_.end(), formDeathCallback);
345 if (iter != formDeathCallbacks_.end()) {
346 formDeathCallbacks_.erase(iter);
347 }
348 APP_LOGI("%{public}s end.", __func__);
349 }
350
351 /**
352 * @brief Get death recipient.
353 * @return deathRecipient_.
354 */
GetDeathRecipient() const355 sptr<IRemoteObject::DeathRecipient> FormMgr::GetDeathRecipient() const
356 {
357 return deathRecipient_;
358 }
359
360 /**
361 * @brief Check whether the specified death callback is registered in form mgr.
362 * @param formDeathCallback The specified death callback for checking.
363 * @return Return true on success, false on failure.
364 */
CheckIsDeathCallbackRegistered(const std::shared_ptr<FormCallbackInterface> & formDeathCallback)365 bool FormMgr::CheckIsDeathCallbackRegistered(const std::shared_ptr<FormCallbackInterface> &formDeathCallback)
366 {
367 APP_LOGI("%{public}s called.", __func__);
368
369 auto iter = std::find(formDeathCallbacks_.begin(), formDeathCallbacks_.end(), formDeathCallback);
370 if (iter != formDeathCallbacks_.end()) {
371 return true;
372 }
373
374 return false;
375 }
376
377 /**
378 * @brief Notices IRemoteBroker died.
379 * @param remote remote object.
380 */
OnRemoteDied(const wptr<IRemoteObject> & remote)381 void FormMgr::FormMgrDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
382 {
383 APP_LOGI("%{public}s called.", __func__);
384
385 if (remote == nullptr) {
386 APP_LOGE("%{public}s failed, remote is nullptr.", __func__);
387 return;
388 }
389
390 if (FormMgr::GetInstance().GetRecoverStatus() == Constants::IN_RECOVERING) {
391 APP_LOGW("%{public}s, fms in recovering.", __func__);
392 return;
393 }
394 // Reset proxy
395 FormMgr::GetInstance().ResetProxy(remote);
396
397 if (!FormMgr::GetInstance().Reconnect()) {
398 APP_LOGE("%{public}s, form mgr service died, try to reconnect to fms failed.", __func__);
399 FormMgr::GetInstance().SetRecoverStatus(Constants::RECOVER_FAIL);
400 return;
401 }
402
403 // refresh form host.
404 for (auto &deathCallback : FormMgr::GetInstance().formDeathCallbacks_) {
405 deathCallback->OnDeathReceived();
406 }
407 FormMgr::GetInstance().SetRecoverStatus(Constants::NOT_IN_RECOVERY);
408 }
409
410 /**
411 * @brief Reconnect form manager service once per 1000 milliseconds,
412 * until the connection succeeds or reaching the max retry times.
413 * @return Returns true if execute success, false otherwise.
414 */
Reconnect()415 bool FormMgr::Reconnect()
416 {
417 APP_LOGI("%{public}s called.", __func__);
418
419 for (int i = 0; i < Constants::MAX_RETRY_TIME; i++) {
420 // Sleep 1000 milliseconds before reconnect.
421 std::this_thread::sleep_for(std::chrono::milliseconds(Constants::SLEEP_TIME));
422
423 // try to connect fms
424 if (Connect() != ERR_OK) {
425 APP_LOGE("%{public}s, get fms proxy fail, try again.", __func__);
426 continue;
427 }
428
429 APP_LOGI("%{public}s, get fms proxy success.", __func__);
430 return true;
431 }
432
433 return false;
434 }
435
436 /**
437 * @brief Connect form manager service.
438 * @return Returns ERR_OK on success, others on failure.
439 */
Connect()440 ErrCode FormMgr::Connect()
441 {
442 std::lock_guard<std::mutex> lock(connectMutex_);
443 if (remoteProxy_ != nullptr && !resetFlag_) {
444 return ERR_OK;
445 }
446
447 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
448 if (systemManager == nullptr) {
449 APP_LOGE("%{private}s:fail to get registry", __func__);
450 return ERR_APPEXECFWK_FORM_GET_SYSMGR_FAILED;
451 }
452 sptr<IRemoteObject> remoteObject = systemManager->GetSystemAbility(FORM_MGR_SERVICE_ID);
453 if (remoteObject == nullptr) {
454 APP_LOGE("%{private}s:fail to connect FormMgrService", __func__);
455 return ERR_APPEXECFWK_FORM_GET_FMS_FAILED;
456 }
457 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new FormMgrDeathRecipient());
458 if (deathRecipient_ == nullptr) {
459 APP_LOGE("%{public}s :Failed to create FormMgrDeathRecipient!", __func__);
460 return ERR_APPEXECFWK_FORM_COMMON_CODE;
461 }
462 if ((remoteObject->IsProxyObject()) && (!remoteObject->AddDeathRecipient(deathRecipient_))) {
463 APP_LOGE("%{public}s :Add death recipient to FormMgrService failed.", __func__);
464 return ERR_APPEXECFWK_FORM_COMMON_CODE;
465 }
466
467 remoteProxy_ = iface_cast<IFormMgr>(remoteObject);
468 APP_LOGD("%{public}s :Connecting FormMgrService success.", __func__);
469 return ERR_OK;
470 }
471
472 /**
473 * @brief Reset proxy.
474 * @param remote remote object.
475 */
ResetProxy(const wptr<IRemoteObject> & remote)476 void FormMgr::ResetProxy(const wptr<IRemoteObject> &remote)
477 {
478 APP_LOGI("%{public}s called.", __func__);
479
480 std::lock_guard<std::mutex> lock(connectMutex_);
481 if (remoteProxy_ == nullptr) {
482 APP_LOGE("%{public}s failed, remote proxy is nullptr.", __func__);
483 return;
484 }
485
486 // set formMgr's recover status to IN_RECOVERING.
487 recoverStatus_ = Constants::IN_RECOVERING;
488
489 // remove the death recipient
490 auto serviceRemote = remoteProxy_->AsObject();
491 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
492 serviceRemote->RemoveDeathRecipient(deathRecipient_);
493 }
494 // clearn the remote proxy
495 remoteProxy_ = nullptr;
496 }
497
498 /**
499 * @brief Set form mgr service for test.
500 */
SetFormMgrService(sptr<IFormMgr> formMgrService)501 void FormMgr::SetFormMgrService(sptr<IFormMgr> formMgrService)
502 {
503 APP_LOGI("%{public}s called.", __func__);
504 remoteProxy_ = formMgrService;
505 }
506 } // namespace AppExecFwk
507 } // namespace OHOS
508