• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "fms_log_wrapper.h"
23 #include "form_constants.h"
24 #include "form_render_service_extension.h"
25 #include "form_util.h"
26 #include "js_runtime.h"
27 #include "service_extension.h"
28 
29 namespace OHOS {
30 namespace AppExecFwk {
31 namespace FormRender {
32 namespace {
33 constexpr int32_t RENDER_FORM_FAILED = -1;
34 constexpr int32_t RELOAD_FORM_FAILED = -1;
35 }
36 using namespace AbilityRuntime;
37 
FormRenderServiceCreator(const std::unique_ptr<Runtime> & runtime)38 static OHOS::AbilityRuntime::ServiceExtension *FormRenderServiceCreator(const std::unique_ptr<Runtime> &runtime)
39 {
40     HILOG_DEBUG("Create FormRenderServiceExtension");
41     return FormRenderServiceExtension::Create(runtime);
42 }
43 
RegisterServiceExtensionCreator()44 __attribute__((constructor)) void RegisterServiceExtensionCreator()
45 {
46     HILOG_DEBUG("Set FormRenderServiceExtension creator");
47     OHOS::AbilityRuntime::ServiceExtension::SetCreator(FormRenderServiceCreator);
48 }
49 
50 FormRenderImpl::FormRenderImpl() = default;
51 FormRenderImpl::~FormRenderImpl() = default;
52 
RenderForm(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)53 int32_t FormRenderImpl::RenderForm(const FormJsInfo &formJsInfo, const Want &want,
54                                    const sptr<IRemoteObject> &callerToken)
55 {
56     HILOG_INFO("Render form, bundleName = %{public}s, abilityName = %{public}s, formName = %{public}s,"
57         "moduleName = %{public}s, jsFormCodePath = %{public}s, formSrc = %{public}s",
58         formJsInfo.bundleName.c_str(), formJsInfo.abilityName.c_str(), formJsInfo.formName.c_str(),
59         formJsInfo.moduleName.c_str(), formJsInfo.jsFormCodePath.c_str(), formJsInfo.formSrc.c_str());
60 
61     sptr<IFormSupply> formSupplyClient = iface_cast<IFormSupply>(callerToken);
62     if (formSupplyClient == nullptr) {
63         HILOG_ERROR("%{public}s warn, IFormSupply is nullptr", __func__);
64         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
65     }
66     {
67         std::lock_guard<std::mutex> lock(formSupplyMutex_);
68         formSupplyClient_ = formSupplyClient;
69     }
70     HILOG_DEBUG("%{public}s come, connectId: %{public}d.", __func__,
71         want.GetIntParam(Constants::FORM_CONNECT_ID, 0L));
72 
73     std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
74     if (uid.empty()) {
75         HILOG_ERROR("GetUid failed");
76         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
77     }
78     int32_t result = ERR_OK;
79     sptr<IRemoteObject> hostToken = want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN);
80     {
81         std::lock_guard<std::mutex> lock(renderRecordMutex_);
82         if (auto search = renderRecordMap_.find(uid); search != renderRecordMap_.end()) {
83             result = search->second->UpdateRenderRecord(formJsInfo, want, hostToken);
84         } else {
85             auto record = FormRenderRecord::Create(formJsInfo.bundleName, uid, formJsInfo.isDynamic);
86             if (record == nullptr) {
87                 HILOG_ERROR("record is nullptr");
88                 return RENDER_FORM_FAILED;
89             }
90 
91             record->SetConfiguration(configuration_);
92             result = record->UpdateRenderRecord(formJsInfo, want, hostToken);
93             renderRecordMap_.emplace(uid, record);
94         }
95     }
96     formSupplyClient->OnRenderTaskDone(formJsInfo.formId, want);
97     return result;
98 }
99 
StopRenderingForm(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)100 int32_t FormRenderImpl::StopRenderingForm(const FormJsInfo &formJsInfo, const Want &want, const sptr<IRemoteObject> &callerToken)
101 {
102     HILOG_INFO("%{public}s called.", __func__);
103     sptr<IFormSupply> formSupplyClient = iface_cast<IFormSupply>(callerToken);
104     if (formSupplyClient == nullptr) {
105         HILOG_ERROR("%{public}s warn, IFormSupply is nullptr", __func__);
106         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
107     }
108 
109     std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
110     if (uid.empty()) {
111         HILOG_ERROR("GetUid failed");
112         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
113     }
114 
115     bool isRenderGroupEmpty = false;
116     sptr<IRemoteObject> hostToken = want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN);
117     {
118         std::lock_guard<std::mutex> lock(renderRecordMutex_);
119         auto search = renderRecordMap_.find(uid);
120         if (search == renderRecordMap_.end()) {
121             HILOG_ERROR("%{public}s failed", __func__ );
122             return RENDER_FORM_FAILED;
123         }
124 
125         if (!search->second) {
126             HILOG_ERROR("%{public}s failed", __func__ );
127             return RENDER_FORM_FAILED;
128         }
129 
130         std::string compId = want.GetStringParam(Constants::FORM_RENDER_COMP_ID);
131         search->second->DeleteRenderRecord(formJsInfo.formId, compId, hostToken, isRenderGroupEmpty);
132         if (search->second->IsEmpty()) {
133             renderRecordMap_.erase(search);
134             HILOG_INFO("DeleteRenderRecord success, uid: %{public}s", uid.c_str());
135         }
136     }
137 
138     HILOG_INFO("%{public}s come, connectId: %{public}d.", __func__,
139         want.GetIntParam(Constants::FORM_CONNECT_ID, 0L));
140     if (isRenderGroupEmpty) {
141         formSupplyClient->OnStopRenderingTaskDone(formJsInfo.formId, want);
142     }
143 
144     return ERR_OK;
145 }
146 
ReleaseRenderer(int64_t formId,const std::string & compId,const std::string & uid)147 int32_t FormRenderImpl::ReleaseRenderer(int64_t formId, const std::string &compId, const std::string &uid)
148 {
149     HILOG_INFO("%{public}s start.", __func__);
150     if (formId <= 0 || compId.empty() || uid.empty()) {
151         HILOG_ERROR("param invalid");
152         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
153     }
154 
155     std::lock_guard<std::mutex> lock(renderRecordMutex_);
156     bool isRenderGroupEmpty = false;
157     auto search = renderRecordMap_.find(uid);
158     if (search == renderRecordMap_.end()) {
159         HILOG_ERROR("%{public}s failed", __func__);
160         return RENDER_FORM_FAILED;
161     }
162 
163     if (!search->second) {
164         HILOG_ERROR("%{public}s failed", __func__);
165         return RENDER_FORM_FAILED;
166     }
167 
168     search->second->ReleaseRenderer(formId, compId, isRenderGroupEmpty);
169     HILOG_INFO("%{public}s end, isRenderGroupEmpty: %{public}d",
170         __func__, isRenderGroupEmpty);
171     if (isRenderGroupEmpty) {
172         search->second->Release();
173     }
174 
175     return ERR_OK;
176 }
177 
CleanFormHost(const sptr<IRemoteObject> & hostToken)178 int32_t FormRenderImpl::CleanFormHost(const sptr<IRemoteObject> &hostToken)
179 {
180     HILOG_INFO("Form host is died, clean renderRecord.");
181     std::lock_guard<std::mutex> lock(renderRecordMutex_);
182     for (auto iter = renderRecordMap_.begin(); iter != renderRecordMap_.end();) {
183         auto renderRecord = iter->second;
184         if (renderRecord && renderRecord->HandleHostDied(hostToken)) {
185             HILOG_DEBUG("renderRecord is empty, remove.");
186             iter = renderRecordMap_.erase(iter);
187         } else {
188             ++iter;
189         }
190     }
191     if (renderRecordMap_.empty()) {
192         HILOG_INFO("renderRecordMap_ is empty, FormRenderService will exit later.");
193     }
194     return ERR_OK;
195 }
196 
ReloadForm(const std::vector<FormJsInfo> && formJsInfos,const Want & want)197 int32_t FormRenderImpl::ReloadForm(const std::vector<FormJsInfo> &&formJsInfos, const Want &want)
198 {
199     HILOG_INFO("ReloadForm start");
200     std::lock_guard<std::mutex> lock(renderRecordMutex_);
201     std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
202     if (uid.empty()) {
203         HILOG_ERROR("Get uid failed");
204         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
205     }
206     auto search = renderRecordMap_.find(uid);
207     if (search == renderRecordMap_.end()) {
208         HILOG_ERROR("RenderRecord not find");
209         return RELOAD_FORM_FAILED;
210     }
211     if (search->second) {
212         search->second->ReloadFormRecord(std::forward<decltype(formJsInfos)>(formJsInfos), want);
213     }
214     return ERR_OK;
215 }
216 
OnUnlock()217 int32_t FormRenderImpl::OnUnlock()
218 {
219     HILOG_INFO("OnUnlock start");
220     std::lock_guard<std::mutex> lock(renderRecordMutex_);
221     for (const auto& iter : renderRecordMap_) {
222         if (iter.second) {
223             iter.second->OnUnlock();
224         }
225     }
226     return ERR_OK;
227 }
228 
OnConfigurationUpdated(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & configuration)229 void FormRenderImpl::OnConfigurationUpdated(
230     const std::shared_ptr<OHOS::AppExecFwk::Configuration>& configuration)
231 {
232     HILOG_INFO("OnConfigurationUpdated start");
233     std::lock_guard<std::mutex> lock(renderRecordMutex_);
234     if (!configuration) {
235         HILOG_ERROR("configuration is nullptr");
236         return;
237     }
238 
239     SetConfiguration(configuration);
240     for (auto iter = renderRecordMap_.begin(); iter != renderRecordMap_.end(); ++iter) {
241         if (iter->second) {
242             iter->second->UpdateConfiguration(configuration);
243         }
244     }
245 }
246 
SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)247 void FormRenderImpl::SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
248 {
249     configuration_ = config;
250 }
251 
OnRenderingBlock(const std::string & bundleName)252 void FormRenderImpl::OnRenderingBlock(const std::string &bundleName)
253 {
254     sptr<IFormSupply> formSupplyClient = nullptr;
255     {
256         std::lock_guard<std::mutex> lock(formSupplyMutex_);
257         formSupplyClient = formSupplyClient_;
258     }
259 
260     if (formSupplyClient == nullptr) {
261         HILOG_ERROR("formSupplyClient_ is nullptr");
262         return;
263     }
264 
265     formSupplyClient->OnRenderingBlock(bundleName);
266 }
267 } // namespace FormRender
268 } // namespace AppExecFwk
269 } // namespace OHOS
270