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
16 #include "form_render_impl.h"
17
18 #include <cstddef>
19 #include <memory>
20
21 #include "event_handler.h"
22 #include "form_constants.h"
23 #include "form_render_service_extension.h"
24 #include "form_supply_proxy.h"
25 #include "form_util.h"
26 #include "hilog_wrapper.h"
27 #include "js_runtime.h"
28 #include "service_extension.h"
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace FormRender {
33 namespace {
34 constexpr int32_t RENDER_FORM_FAILED = -1;
35 constexpr int32_t RELOAD_FORM_FAILED = -1;
36 }
37 using namespace AbilityRuntime;
38
FormRenderServiceCreator(const std::unique_ptr<Runtime> & runtime)39 static OHOS::AbilityRuntime::ServiceExtension *FormRenderServiceCreator(const std::unique_ptr<Runtime> &runtime)
40 {
41 HILOG_DEBUG("Create FormRenderServiceExtension");
42 return FormRenderServiceExtension::Create(runtime);
43 }
44
RegisterServiceExtensionCreator()45 __attribute__((constructor)) void RegisterServiceExtensionCreator()
46 {
47 HILOG_DEBUG("Set FormRenderServiceExtension creator");
48 OHOS::AbilityRuntime::ServiceExtension::SetCreator(FormRenderServiceCreator);
49 }
50
51 FormRenderImpl::FormRenderImpl() = default;
52 FormRenderImpl::~FormRenderImpl() = default;
53
RenderForm(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)54 int32_t FormRenderImpl::RenderForm(const FormJsInfo &formJsInfo, const Want &want,
55 const sptr<IRemoteObject> &callerToken)
56 {
57 HILOG_INFO("Render form, bundleName = %{public}s, abilityName = %{public}s, formName = %{public}s,"
58 "moduleName = %{public}s, jsFormCodePath = %{public}s, formSrc = %{public}s",
59 formJsInfo.bundleName.c_str(), formJsInfo.abilityName.c_str(), formJsInfo.formName.c_str(),
60 formJsInfo.moduleName.c_str(), formJsInfo.jsFormCodePath.c_str(), formJsInfo.formSrc.c_str());
61
62 sptr<IFormSupply> formSupplyClient = iface_cast<IFormSupply>(callerToken);
63 if (formSupplyClient == nullptr) {
64 HILOG_ERROR("%{public}s warn, IFormSupply is nullptr", __func__);
65 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
66 }
67 HILOG_DEBUG("%{public}s come, connectId: %{public}d.", __func__,
68 want.GetIntParam(Constants::FORM_CONNECT_ID, 0L));
69
70 std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
71 if (uid.empty()) {
72 HILOG_ERROR("GetUid failed");
73 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
74 }
75 int32_t result = ERR_OK;
76 sptr<IRemoteObject> hostToken = want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN);
77 {
78 std::lock_guard<std::mutex> lock(renderRecordMutex_);
79 if (auto search = renderRecordMap_.find(uid); search != renderRecordMap_.end()) {
80 result = search->second->UpdateRenderRecord(formJsInfo, want, hostToken);
81 } else {
82 auto record = FormRenderRecord::Create(formJsInfo.bundleName, uid);
83 result = record->UpdateRenderRecord(formJsInfo, want, hostToken);
84 renderRecordMap_.emplace(uid, record);
85 }
86 }
87 formSupplyClient->OnRenderTaskDone(formJsInfo.formId, want);
88 return result;
89 }
90
StopRenderingForm(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)91 int32_t FormRenderImpl::StopRenderingForm(const FormJsInfo &formJsInfo, const Want &want, const sptr<IRemoteObject> &callerToken)
92 {
93 HILOG_INFO("%{public}s called.", __func__);
94 sptr<IFormSupply> formSupplyClient = iface_cast<IFormSupply>(callerToken);
95 if (formSupplyClient == nullptr) {
96 HILOG_ERROR("%{public}s warn, IFormSupply is nullptr", __func__);
97 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
98 }
99
100 std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
101 if (uid.empty()) {
102 HILOG_ERROR("GetUid failed");
103 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
104 }
105
106 bool isRenderGroupEmpty = false;
107 sptr<IRemoteObject> hostToken = want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN);
108 {
109 std::lock_guard<std::mutex> lock(renderRecordMutex_);
110 auto search = renderRecordMap_.find(uid);
111 if (search == renderRecordMap_.end()) {
112 HILOG_ERROR("%{public}s failed", __func__ );
113 return RENDER_FORM_FAILED;
114 }
115
116 if (!search->second) {
117 HILOG_ERROR("%{public}s failed", __func__ );
118 return RENDER_FORM_FAILED;
119 }
120
121 std::string compId = want.GetStringParam(Constants::FORM_RENDER_COMP_ID);
122 search->second->DeleteRenderRecord(formJsInfo.formId, compId, hostToken, isRenderGroupEmpty);
123 if (search->second->IsEmpty()) {
124 renderRecordMap_.erase(search);
125 HILOG_INFO("DeleteRenderRecord success, uid: %{public}s", uid.c_str());
126 }
127 }
128
129 HILOG_INFO("%{public}s come, connectId: %{public}d.", __func__,
130 want.GetIntParam(Constants::FORM_CONNECT_ID, 0L));
131 if (isRenderGroupEmpty) {
132 formSupplyClient->OnStopRenderingTaskDone(formJsInfo.formId, want);
133 }
134
135 return ERR_OK;
136 }
137
CleanFormHost(const sptr<IRemoteObject> & hostToken)138 int32_t FormRenderImpl::CleanFormHost(const sptr<IRemoteObject> &hostToken)
139 {
140 HILOG_INFO("Form host is died, clean renderRecord.");
141 std::lock_guard<std::mutex> lock(renderRecordMutex_);
142 for (auto iter = renderRecordMap_.begin(); iter != renderRecordMap_.end();) {
143 auto renderRecord = iter->second;
144 if (renderRecord && renderRecord->HandleHostDied(hostToken)) {
145 HILOG_DEBUG("renderRecord is empty, remove.");
146 iter = renderRecordMap_.erase(iter);
147 } else {
148 ++iter;
149 }
150 }
151 if (renderRecordMap_.empty()) {
152 HILOG_INFO("renderRecordMap_ is empty, FormRenderService will exit later.");
153 }
154 return ERR_OK;
155 }
156
ReloadForm(const std::vector<int64_t> && formIds,const Want & want)157 int32_t FormRenderImpl::ReloadForm(const std::vector<int64_t> &&formIds, const Want &want)
158 {
159 HILOG_INFO("ReloadForm start");
160 std::lock_guard<std::mutex> lock(renderRecordMutex_);
161 std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
162 if (uid.empty()) {
163 HILOG_ERROR("Get uid failed");
164 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
165 }
166 auto search = renderRecordMap_.find(uid);
167 if (search == renderRecordMap_.end()) {
168 HILOG_ERROR("RenderRecord not find");
169 return RELOAD_FORM_FAILED;
170 }
171 if (search->second) {
172 search->second->ReloadFormRecord(std::forward<decltype(formIds)>(formIds), want);
173 }
174 return ERR_OK;
175 }
176
OnConfigurationUpdated(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & configuration)177 void FormRenderImpl::OnConfigurationUpdated(
178 const std::shared_ptr<OHOS::AppExecFwk::Configuration>& configuration)
179 {
180 HILOG_INFO("OnConfigurationUpdated start");
181 std::lock_guard<std::mutex> lock(renderRecordMutex_);
182 for (auto iter = renderRecordMap_.begin(); iter != renderRecordMap_.end(); ++iter) {
183 if (iter->second) {
184 iter->second->UpdateConfiguration(configuration);
185 }
186 }
187 }
188 } // namespace FormRender
189 } // namespace AppExecFwk
190 } // namespace OHOS
191