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 #ifndef OHOS_FORM_FWK_FORM_RENDER_RECORD_H
17 #define OHOS_FORM_FWK_FORM_RENDER_RECORD_H
18 
19 #include <memory>
20 #include <unordered_map>
21 #include <unordered_set>
22 
23 #include "configuration.h"
24 #include "context_impl.h"
25 #include "event_handler.h"
26 #include "form_js_info.h"
27 #include "form_mgr_errors.h"
28 #include "form_supply_proxy.h"
29 #include "form_renderer_group.h"
30 #include "js_runtime.h"
31 #include "want.h"
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace FormRender {
36 using Want = AAFwk::Want;
37 enum class TaskState {
38     NO_RUNNING = 0,
39     RUNNING = 0,
40     BLOCK,
41 };
42 
43 class ThreadState {
44 public:
45     explicit ThreadState(int32_t maxState);
46     void ResetState();
47     void NextState();
48     int32_t GetCurrentState();
49     bool IsMaxState();
50 
51 private:
52     int32_t state_ = 0;
53     int32_t maxState_;
54 };
55 
56 class HandlerDumper : public AppExecFwk::Dumper {
57 public:
58     void Dump(const std::string &message) override;
59     std::string GetTag() override;
60     std::string GetDumpInfo();
61 private:
62     std::string dumpInfo_;
63 };
64 
65 class FormRenderRecord : public std::enable_shared_from_this<FormRenderRecord> {
66 public:
67     /**
68      * @brief Create a FormRenderRecord.
69      * @param bundleName The bundleName of form bundle.
70      * @param uid The uid of form bundle.(userId + bundleName)
71      * @return Returns FormRenderRecord instance.
72      */
73     static std::shared_ptr<FormRenderRecord> Create(const std::string &bundleName, const std::string &uid,
74         bool needMonitored = true, sptr<IFormSupply> formSupplyClient = nullptr);
75 
76     FormRenderRecord(const std::string &bundleName, const std::string &uid, sptr<IFormSupply> formSupplyClient);
77 
78     ~FormRenderRecord();
79 
80     /**
81      * @brief When the host exits, clean up related resources.
82      * @param hostRemoteObj host token.
83      * @return Returns TRUE: FormRenderRecord is empty, FALSE: FormRenderRecord is not empty.
84      */
85     bool HandleHostDied(const sptr<IRemoteObject> hostRemoteObj);
86 
87     /**
88      * @brief When add a new form, the corresponding FormRenderRecord needs to be updated.
89      * @param formJsInfo formJsInfo.
90      * @param want want.
91      * @param hostRemoteObj host token.
92      * @return Returns ERR_OK on success, others on failure.
93      */
94     int32_t UpdateRenderRecord(const FormJsInfo &formJsInfo, const Want &want, const sptr<IRemoteObject> hostRemoteObj);
95 
96     /**
97      * @brief When all forms of an bundle are deleted, the corresponding FormRenderRecord-record needs to be removed
98      * @param formId formId.
99      * @param hostRemoteObj host token.
100      * @return Returns ERR_OK on success, others on failure.
101      */
102     void DeleteRenderRecord(int64_t formId, const std::string &compId,  const sptr<IRemoteObject> hostRemoteObj,
103         bool &isRenderGroupEmpty);
104 
105     int32_t HandleOnUnlock();
106 
107     int32_t OnUnlock();
108 
109     int32_t SetVisibleChange(const int64_t &formId, bool isVisible);
110 
111     int32_t HandleSetVisibleChange(const int64_t &formId, bool isVisible);
112 
113     int32_t ReloadFormRecord(const std::vector<FormJsInfo> &&formJsInfos, const Want &want);
114 
115     int32_t HandleReloadFormRecord(const std::vector<FormJsInfo> &&formJsInfos, const Want &want);
116 
117     /**
118      * @brief Get the uid of bundle.
119      * @return Returns the uid.
120      */
121     std::string GetUid() const;
122 
123     bool IsEmpty();
124 
125     void UpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config,
126         const sptr<IFormSupply> &formSupplyClient);
127 
128     void SetConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config);
129 
130     void MarkThreadAlive();
131 
132     void ReleaseRenderer(int64_t formId, const std::string &compId, bool &isRenderGroupEmpty);
133 
134     void Release();
135 
136     void FormRenderGC();
137 
138     int32_t RecycleForm(const int64_t &formId, std::string &statusData);
139 
140     int32_t RecoverForm(const FormJsInfo &formJsInfo, const std::string &statusData,
141         const bool &isRecoverFormToHandleClickEvent);
142 
143     size_t FormCount();
144 
145     void UpdateFormSizeOfGroups(const int64_t &formId, float width, float height, float borderWidth);
146 private:
147     class RemoteObjHash {
148     public:
operator()149         size_t operator() (const sptr<IRemoteObject> remoteObj) const
150         {
151             return reinterpret_cast<size_t>(remoteObj.GetRefPtr());
152         }
153     };
154     using IRemoteObjectSet = std::unordered_set<sptr<IRemoteObject>, RemoteObjHash>;
155 
156     bool CreateEventHandler(const std::string &bundleName, bool needMonitored = true);
157 
158     bool CreateRuntime(const FormJsInfo &formJsInfo);
159 
160     bool UpdateRuntime(const FormJsInfo &formJsInfo);
161 
162     bool SetPkgContextInfoMap(const FormJsInfo &formJsInfo, AbilityRuntime::Runtime::Options &options);
163 
164     std::shared_ptr<AbilityRuntime::Context> GetContext(const FormJsInfo &formJsInfo, const Want &want);
165 
166     std::shared_ptr<AbilityRuntime::Context> CreateContext(const FormJsInfo &formJsInfo, const Want &want);
167 
168     std::shared_ptr<Ace::FormRendererGroup> GetFormRendererGroup(const FormJsInfo &formJsInfo,
169     const std::shared_ptr<AbilityRuntime::Context> &context, const std::shared_ptr<AbilityRuntime::Runtime> &runtime);
170 
171     std::shared_ptr<Ace::FormRendererGroup> CreateFormRendererGroupLock(const FormJsInfo &formJsInfo,
172     const std::shared_ptr<AbilityRuntime::Context> &context, const std::shared_ptr<AbilityRuntime::Runtime> &runtime);
173 
174     void HandleUpdateInJsThread(const FormJsInfo &formJsInfo, const Want &want);
175 
176     bool HandleDeleteInJsThread(int64_t formId, const std::string &compId);
177 
178     void HandleDestroyInJsThread();
179 
180     bool HandleReleaseRendererInJsThread(int64_t formId, const std::string &compId, bool &isRenderGroupEmpty);
181 
182     void DeleteRendererGroup(int64_t formId);
183 
184     void HandleDeleteRendererGroup(int64_t formId);
185 
186     std::string GenerateContextKey(const FormJsInfo &formJsInfo);
187 
188     void ReleaseHapFileHandle();
189 
190     void HandleUpdateConfiguration(const std::shared_ptr<OHOS::AppExecFwk::Configuration>& config);
191 
192     void AddWatchDogThreadMonitor();
193 
194     void OnRenderingBlock(const std::string &bundleName);
195 
196     void OnNotifyRefreshForm(const int64_t &formId);
197 
198     void Timer();
199 
200     bool BeforeHandleUpdateForm(const FormJsInfo &formJsInfo);
201 
202     void HandleUpdateForm(const FormJsInfo &formJsInfo, const Want &want);
203 
204     void MergeFormData(Ace::FormRequest &formRequest, const FormJsInfo &formJsInfo);
205 
206     void AddRenderer(const FormJsInfo &formJsInfo, const Want &want);
207 
208     void UpdateRenderer(const FormJsInfo &formJsInfo);
209 
210     TaskState RunTask();
211 
212     void DumpEventHandler();
213 
214     void HandleReleaseInJsThread();
215 
216     bool CheckEventHandler(bool createThead = true, bool needMonitored = false);
217 
218     void AddFormRequest(const FormJsInfo &formJsInfo, const Want &want);
219 
220     void AddFormRequest(int64_t formId, Ace::FormRequest &formRequest);
221 
222     /**
223      * @brief Add formRequest to formRequests_.
224      * @param formId formId.
225      * @param formRequest formRequest.
226      * @param noNeedUpdateSize If form size is modified in the
227      * formRequest parameter, this parameter should be set to false.
228      * Set this parameter to true if you want to keep the form size data in the formRequests_.
229      */
230     void AddFormRequest(int64_t formId, Ace::FormRequest &formRequest, bool noNeedUpdateSize);
231 
232     void DeleteFormRequest(int64_t formId, const std::string &compId);
233 
234     void UpdateFormRequestReleaseState(
235         int64_t formId, const std::string &compId, bool hasRelease);
236 
237     void RecoverFormsByConfigUpdate(std::vector<int64_t> &formIds, const sptr<IFormSupply> &formSupplyClient);
238 
239     void ReAddAllRecycledForms(const sptr<IFormSupply> &formSupplyClient);
240 
241     void ReAddRecycledForms(const std::vector<FormJsInfo> &formJsInfos);
242 
243     int32_t HandleRecycleForm(const int64_t &formId, std::string &statusData);
244 
245     void HandleRecoverForm(const FormJsInfo &formJsInfo, const std::string &statusData,
246         const bool &isRecoverFormToHandleClickEvent);
247 
248     void HandleFormRenderGC();
249 
250     bool InitCompIds(const int64_t &formId,
251         std::vector<std::string> &orderedCompIds, std::string &currentCompId);
252 
253     bool RecoverFormRequestsInGroup(const FormJsInfo &formJsInfo, const std::string &statusData,
254         const bool &isHandleClickEvent, std::unordered_map<std::string, Ace::FormRequest> &recordFormRequests);
255     bool RecoverRenderer(const std::vector<Ace::FormRequest> &groupRequests, const size_t &currentRequestIndex);
256 
257     bool ReAddIfHapPathChanged(const std::vector<FormJsInfo> &formJsInfos);
258 
259     void UpdateAllFormRequest(const std::vector<FormJsInfo> &formJsInfos, bool hasRelease);
260 
261     void HandleReleaseAllRendererInJsThread();
262 
263     void UpdateGroupRequestsWhenRecover(const int64_t &formId, const FormJsInfo &formJsInfo,
264         const std::vector<std::string> &orderedCompIds, const std::string &currentCompId,
265         const std::string &statusData, const bool &isHandleClickEvent, size_t &currentRequestIndex,
266         std::vector<Ace::FormRequest> &groupRequests, bool &currentRequestFound,
267         const std::unordered_map<std::string, Ace::FormRequest> &recordFormRequests);
268 
269     pid_t jsThreadId_ = 0;
270     pid_t processId_ = 0;
271 
272     std::string bundleName_;
273     std::string uid_;
274     std::shared_ptr<EventRunner> eventRunner_;
275     std::shared_ptr<EventHandler> eventHandler_;
276     std::mutex eventHandlerMutex_;
277     std::shared_ptr<AbilityRuntime::Runtime> runtime_;
278 
279     // <formId, hostRemoteObj>
280     std::mutex hostsMapMutex_;
281     std::unordered_map<int64_t, IRemoteObjectSet> hostsMapForFormId_;
282     // <moduleName, Context>
283     std::mutex contextsMapMutex_;
284     std::unordered_map<std::string, std::shared_ptr<AbilityRuntime::Context>> contextsMapForModuleName_;
285     // <formId, formRendererGroup>
286     std::mutex formRendererGroupMutex_;
287     std::unordered_map<int64_t, std::shared_ptr<Ace::FormRendererGroup>> formRendererGroupMap_;
288     // <formId, <compId, formRequest>>
289     std::mutex formRequestsMutex_;
290     std::unordered_map<int64_t, std::unordered_map<std::string, Ace::FormRequest>> formRequests_;
291     std::shared_ptr<OHOS::AppExecFwk::Configuration> configuration_;
292     // <formId, <orderedCompIds, currentCompId>>
293     std::mutex recycledFormCompIdsMutex_;
294     std::unordered_map<int64_t, std::pair<std::vector<std::string>, std::string>> recycledFormCompIds_;
295 
296     std::string hapPath_;
297     std::mutex watchDogMutex_;
298     bool threadIsAlive_ = true;
299     std::atomic_bool hasMonitor_ = false;
300     std::shared_ptr<ThreadState> threadState_;
301     std::mutex formSupplyMutex_;
302     sptr<IFormSupply> formSupplyClient_;
303 };
304 }  // namespace FormRender
305 }  // namespace AppExecFwk
306 }  // namespace OHOS
307 #endif  // OHOS_FORM_FWK_FORM_RENDER_RECORD_H
308