• 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 "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             if (record == nullptr) {
84                 HILOG_ERROR("record is nullptr");
85                 return RENDER_FORM_FAILED;
86             }
87 
88             record->SetConfiguration(configuration_);
89             result = record->UpdateRenderRecord(formJsInfo, want, hostToken);
90             renderRecordMap_.emplace(uid, record);
91         }
92     }
93     formSupplyClient->OnRenderTaskDone(formJsInfo.formId, want);
94     return result;
95 }
96 
StopRenderingForm(const FormJsInfo & formJsInfo,const Want & want,const sptr<IRemoteObject> & callerToken)97 int32_t FormRenderImpl::StopRenderingForm(const FormJsInfo &formJsInfo, const Want &want, const sptr<IRemoteObject> &callerToken)
98 {
99     HILOG_INFO("%{public}s called.", __func__);
100     sptr<IFormSupply> formSupplyClient = iface_cast<IFormSupply>(callerToken);
101     if (formSupplyClient == nullptr) {
102         HILOG_ERROR("%{public}s warn, IFormSupply is nullptr", __func__);
103         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
104     }
105 
106     std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
107     if (uid.empty()) {
108         HILOG_ERROR("GetUid failed");
109         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
110     }
111 
112     bool isRenderGroupEmpty = false;
113     sptr<IRemoteObject> hostToken = want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN);
114     {
115         std::lock_guard<std::mutex> lock(renderRecordMutex_);
116         auto search = renderRecordMap_.find(uid);
117         if (search == renderRecordMap_.end()) {
118             HILOG_ERROR("%{public}s failed", __func__ );
119             return RENDER_FORM_FAILED;
120         }
121 
122         if (!search->second) {
123             HILOG_ERROR("%{public}s failed", __func__ );
124             return RENDER_FORM_FAILED;
125         }
126 
127         std::string compId = want.GetStringParam(Constants::FORM_RENDER_COMP_ID);
128         search->second->DeleteRenderRecord(formJsInfo.formId, compId, hostToken, isRenderGroupEmpty);
129         if (search->second->IsEmpty()) {
130             renderRecordMap_.erase(search);
131             HILOG_INFO("DeleteRenderRecord success, uid: %{public}s", uid.c_str());
132         }
133     }
134 
135     HILOG_INFO("%{public}s come, connectId: %{public}d.", __func__,
136         want.GetIntParam(Constants::FORM_CONNECT_ID, 0L));
137     if (isRenderGroupEmpty) {
138         formSupplyClient->OnStopRenderingTaskDone(formJsInfo.formId, want);
139     }
140 
141     return ERR_OK;
142 }
143 
CleanFormHost(const sptr<IRemoteObject> & hostToken)144 int32_t FormRenderImpl::CleanFormHost(const sptr<IRemoteObject> &hostToken)
145 {
146     HILOG_INFO("Form host is died, clean renderRecord.");
147     std::lock_guard<std::mutex> lock(renderRecordMutex_);
148     for (auto iter = renderRecordMap_.begin(); iter != renderRecordMap_.end();) {
149         auto renderRecord = iter->second;
150         if (renderRecord && renderRecord->HandleHostDied(hostToken)) {
151             HILOG_DEBUG("renderRecord is empty, remove.");
152             iter = renderRecordMap_.erase(iter);
153         } else {
154             ++iter;
155         }
156     }
157     if (renderRecordMap_.empty()) {
158         HILOG_INFO("renderRecordMap_ is empty, FormRenderService will exit later.");
159     }
160     return ERR_OK;
161 }
162 
ReloadForm(const std::vector<int64_t> && formIds,const Want & want)163 int32_t FormRenderImpl::ReloadForm(const std::vector<int64_t> &&formIds, const Want &want)
164 {
165     HILOG_INFO("ReloadForm start");
166     std::lock_guard<std::mutex> lock(renderRecordMutex_);
167     std::string uid = want.GetStringParam(Constants::FORM_SUPPLY_UID);
168     if (uid.empty()) {
169         HILOG_ERROR("Get uid failed");
170         return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
171     }
172     auto search = renderRecordMap_.find(uid);
173     if (search == renderRecordMap_.end()) {
174         HILOG_ERROR("RenderRecord not find");
175         return RELOAD_FORM_FAILED;
176     }
177     if (search->second) {
178         search->second->ReloadFormRecord(std::forward<decltype(formIds)>(formIds), want);
179     }
180     return ERR_OK;
181 }
182 
OnConfigurationUpdated(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & configuration)183 void FormRenderImpl::OnConfigurationUpdated(
184     const std::shared_ptr<OHOS::AppExecFwk::Configuration>& configuration)
185 {
186     HILOG_INFO("OnConfigurationUpdated start");
187     std::lock_guard<std::mutex> lock(renderRecordMutex_);
188     if (!configuration) {
189         HILOG_ERROR("configuration is nullptr");
190         return;
191     }
192 
193     SetConfiguration(configuration);
194     for (auto iter = renderRecordMap_.begin(); iter != renderRecordMap_.end(); ++iter) {
195         if (iter->second) {
196             iter->second->UpdateConfiguration(configuration);
197         }
198     }
199 }
200 
SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration> & config)201 void FormRenderImpl::SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config)
202 {
203     configuration_ = config;
204 }
205 } // namespace FormRender
206 } // namespace AppExecFwk
207 } // namespace OHOS
208