• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H
18 
19 #include <mutex>
20 #include <string>
21 #include <unordered_set>
22 #include <functional>
23 #include <vector>
24 
25 #include "base/utils/macros.h"
26 #include "core/animation/animator_info.h"
27 #include "core/common/ace_page.h"
28 #include "core/common/thread_checker.h"
29 #include "core/components/checkable/radio_group_component.h"
30 #include "core/components/page/page_target.h"
31 #include "core/components/page_transition/page_transition_component.h"
32 #include "frameworks/bridge/common/dom/dom_document.h"
33 #include "frameworks/bridge/common/utils/source_map.h"
34 #include "frameworks/bridge/common/utils/utils.h"
35 #include "frameworks/bridge/js_frontend/engine/common/base_animation_bridge.h"
36 #include "frameworks/bridge/js_frontend/engine/common/base_canvas_bridge.h"
37 #include "frameworks/bridge/js_frontend/engine/common/base_xcomponent_bridge.h"
38 #include "frameworks/bridge/js_frontend/js_command.h"
39 
40 namespace OHOS::Ace::Framework {
41 
42 using JsPageRadioGroups = std::unordered_map<std::string, RadioGroupComponent<std::string>>;
43 
44 // One JsAcePage corresponding to a JS bundle, so it should maintain page's lifecycle.
45 class ACE_EXPORT JsAcePage final : public AcePage {
46     DECLARE_ACE_TYPE(JsAcePage, AcePage);
47 
48 public:
49     JsAcePage(int32_t pageId, const RefPtr<DOMDocument>& document, const std::string& url,
50         const WeakPtr<StageElement>& container = nullptr)
AcePage(pageId)51         : AcePage(pageId), domDoc_(document), url_(url), container_(container),
52           radioGroups_(std::make_shared<JsPageRadioGroups>())
53     {
54         ACE_DCHECK(domDoc_);
55     }
56 
57     ~JsAcePage() override;
58 
59     RefPtr<PageComponent> BuildPage(const std::string& url) override;
60     RefPtr<ComposedComponent> BuildPagePatch(int32_t nodeId);
61 
GetDomDocument()62     RefPtr<DOMDocument> GetDomDocument() const
63     {
64         return domDoc_;
65     }
66 
GetUrl()67     const std::string& GetUrl() const
68     {
69         return url_;
70     }
71 
CheckPageCreated()72     bool CheckPageCreated() const
73     {
74         return pageCreated_;
75     }
76 
SetPageCreated()77     void SetPageCreated()
78     {
79         pageCreated_ = true;
80     }
81 
SetPageTransition(const RefPtr<PageTransitionComponent> & pageTransition)82     void SetPageTransition(const RefPtr<PageTransitionComponent>& pageTransition)
83     {
84         pageTransition_ = pageTransition;
85     }
86 
PushCommand(const RefPtr<JsCommand> & jsCommand)87     void PushCommand(const RefPtr<JsCommand>& jsCommand)
88     {
89         jsCommands_.emplace_back(jsCommand);
90     }
91 
PopAllCommands(std::vector<RefPtr<JsCommand>> & jsCommands)92     void PopAllCommands(std::vector<RefPtr<JsCommand>>& jsCommands)
93     {
94         jsCommands = std::move(jsCommands_);
95     }
96 
PushNewNode(NodeId nodeId,NodeId parentNodeId)97     void PushNewNode(NodeId nodeId, NodeId parentNodeId)
98     {
99         CHECK_RUN_ON(UI);
100         dirtyNodes_.emplace(nodeId);
101         PushDirtyNode(parentNodeId);
102     }
103 
PushDirtyNode(NodeId nodeId)104     void PushDirtyNode(NodeId nodeId)
105     {
106         CHECK_RUN_ON(UI);
107         auto result = dirtyNodes_.emplace(nodeId);
108         if (result.second) {
109             dirtyNodesOrderedByTime_.emplace_back(nodeId);
110         }
111     }
112 
PopAllDirtyNodes(std::vector<NodeId> & dirtyNodes)113     void PopAllDirtyNodes(std::vector<NodeId>& dirtyNodes)
114     {
115         CHECK_RUN_ON(UI);
116         dirtyNodes = std::move(dirtyNodesOrderedByTime_);
117         dirtyNodes_.clear();
118     }
119 
ClearAllDirtyNodes()120     void ClearAllDirtyNodes()
121     {
122         CHECK_RUN_ON(UI);
123         dirtyNodesOrderedByTime_.clear();
124         dirtyNodes_.clear();
125     }
126 
ReserveShowCommand(const RefPtr<JsCommand> & command)127     void ReserveShowCommand(const RefPtr<JsCommand>& command)
128     {
129         if (command) {
130             std::unique_lock<std::mutex> lock(cmdMutex_);
131             showCommands_.emplace_back(command);
132         }
133     }
134 
UpdateShowAttr()135     void UpdateShowAttr()
136     {
137         CHECK_RUN_ON(UI);
138         std::unique_lock<std::mutex> lock(cmdMutex_);
139         if (showCommands_.empty()) {
140             return;
141         }
142 
143         for (auto& command : showCommands_) {
144             command->Execute(AceType::Claim(this));
145         }
146         showCommandConsumed_ = true;
147     }
148 
CheckShowCommandConsumed()149     bool CheckShowCommandConsumed() const
150     {
151         return showCommandConsumed_;
152     }
153 
ClearShowCommand()154     void ClearShowCommand()
155     {
156         std::unique_lock<std::mutex> lock(cmdMutex_);
157         showCommands_.clear();
158         showCommandConsumed_ = false;
159     }
160 
161     RefPtr<BaseCanvasBridge> GetBridgeById(NodeId nodeId);
162     void PushCanvasBridge(NodeId nodeId, const RefPtr<BaseCanvasBridge>& bridge);
163     void PushOffscreenCanvasBridge(int32_t bridgeId, const RefPtr<BaseCanvasBridge>& bridge);
164     RefPtr<BaseCanvasBridge> GetOffscreenCanvasBridgeById(int32_t nodeId);
165 
166     RefPtr<BaseXComponentBridge> GetXComponentBridgeById(NodeId nodeId);
167     void PushXComponentBridge(NodeId nodeId, const RefPtr<BaseXComponentBridge>& bridge);
168 
169     RefPtr<BaseAnimationBridge> GetAnimationBridge(NodeId nodeId);
170     void RemoveAnimationBridge(NodeId nodeId);
171     void AddAnimationBridge(NodeId nodeId, const RefPtr<BaseAnimationBridge>& animationBridge);
172 
173     RefPtr<BaseAnimationBridge> GetAnimatorBridge(int32_t bridgeId);
174     void RemoveAnimatorBridge(int32_t bridgeId);
175     void AddAnimatorBridge(int32_t bridgeId, const RefPtr<BaseAnimationBridge>& animatorBridge);
176 
177     RefPtr<Curve> GetCurve(const std::string& curveString);
178     void RemoveCurve(const std::string& curveString);
179     void AddCurve(const std::string& curveString, const RefPtr<Curve>& curve);
180 
181     RefPtr<AnimatorInfo> GetAnimatorInfo(const std::string& animatorId);
182     void RemoveAnimatorInfo(const std::string& animatorId);
183     void AddAnimatorInfo(const std::string animatorId, const RefPtr<AnimatorInfo>& animatorInfo);
184 
SetPageParams(const std::string & params)185     void SetPageParams(const std::string& params)
186     {
187         pageParams_ = params;
188     }
189 
GetPageParams()190     const std::string& GetPageParams() const
191     {
192         return pageParams_;
193     }
194 
SetFlushCallback(std::function<void (const RefPtr<JsAcePage> &)> && callback)195     void SetFlushCallback(std::function<void(const RefPtr<JsAcePage>&)>&& callback)
196     {
197         flushCallback_ = std::move(callback);
198     }
199 
FlushCommands()200     void FlushCommands()
201     {
202         if (flushCallback_) {
203             fragmentCount_++;
204             flushCallback_(AceType::Claim(this));
205         }
206     }
207 
FragmentCount()208     int32_t FragmentCount() const
209     {
210         return fragmentCount_;
211     }
212 
GetCommandSize()213     size_t GetCommandSize() const
214     {
215         return jsCommands_.size();
216     }
217 
SetPipelineContext(const WeakPtr<PipelineContext> & pipelineContext)218     void SetPipelineContext(const WeakPtr<PipelineContext>& pipelineContext)
219     {
220         pipelineContext_ = pipelineContext;
221     }
222 
GetPipelineContext()223     WeakPtr<PipelineContext> GetPipelineContext() const
224     {
225         return pipelineContext_;
226     }
227 
IsLiteStyle()228     bool IsLiteStyle() const
229     {
230         return useLiteStyle_;
231     }
232 
SetUseLiteStyle(bool useLiteStyle)233     void SetUseLiteStyle(bool useLiteStyle)
234     {
235         useLiteStyle_ = useLiteStyle;
236     }
237 
IsUseBoxWrap()238     bool IsUseBoxWrap() const
239     {
240         return useBoxWrap_;
241     }
242 
SetUseBoxWrap(bool useBoxWrap)243     void SetUseBoxWrap(bool useBoxWrap)
244     {
245         useBoxWrap_ = useBoxWrap;
246     }
247 
IsUsePluginComponent()248     bool IsUsePluginComponent() const
249     {
250         return usePluginComponent_;
251     }
252 
SetUsePluginComponent(bool usePluginComponent)253     void SetUsePluginComponent(bool usePluginComponent)
254     {
255         usePluginComponent_ = usePluginComponent;
256     }
257 
GetPluginComponentJsonData()258     const std::string& GetPluginComponentJsonData() const
259     {
260         return pluginComponentJsonData_;
261     }
262 
SetPluginComponentJsonData(const std::string & pluginComponentJsonData)263     void SetPluginComponentJsonData(const std::string& pluginComponentJsonData)
264     {
265         pluginComponentJsonData_ = pluginComponentJsonData;
266     }
267 
268     void AddNodeEvent(int32_t nodeId, const std::string& actionType, const std::string& eventAction);
269 
270     std::string GetNodeEventAction(int32_t nodeId, const std::string& actionType);
271     std::shared_ptr<JsPageRadioGroups> GetRadioGroups();
272 
SetRootComponent(const RefPtr<Component> & component)273     void SetRootComponent(const RefPtr<Component>& component)
274     {
275         component_ = component;
276     }
277 
SetPageMap(const std::string & pageMap)278     void SetPageMap(const std::string& pageMap)
279     {
280         pageMap_ = AceType::MakeRefPtr<RevSourceMap>();
281         pageMap_->Init(pageMap);
282     }
283 
GetPageMap()284     RefPtr<RevSourceMap> GetPageMap() const
285     {
286         return pageMap_;
287     }
288 
SetAppMap(const std::string & appMap)289     void SetAppMap(const std::string& appMap)
290     {
291         appMap_ = AceType::MakeRefPtr<RevSourceMap>();
292         appMap_->Init(appMap);
293     }
294 
GetAppMap()295     RefPtr<RevSourceMap> GetAppMap() const
296     {
297         return appMap_;
298     }
299 
GetStageElement()300     RefPtr<StageElement> GetStageElement() const
301     {
302         return container_.Upgrade();
303     }
304 
SetDeclarativeOnPageAppearCallback(std::function<void ()> && callback)305     void SetDeclarativeOnPageAppearCallback(std::function<void()>&& callback)
306     {
307         onPageAppear_ = callback;
308     }
309 
SetDeclarativeOnPageDisAppearCallback(std::function<void ()> && callback)310     void SetDeclarativeOnPageDisAppearCallback(std::function<void()>&& callback)
311     {
312         onPageDisAppear_ = callback;
313     }
314 
SetDeclarativeOnBackPressCallback(std::function<bool ()> && callback)315     void SetDeclarativeOnBackPressCallback(std::function<bool()>&& callback)
316     {
317         onBackPress_ = callback;
318     }
319 
SetDeclarativeOnPageRefreshCallback(std::function<void ()> && callback)320     void SetDeclarativeOnPageRefreshCallback(std::function<void()>&& callback)
321     {
322         onPageRefresh_ = callback;
323     }
324 
FireDeclarativeOnPageAppearCallback()325     void FireDeclarativeOnPageAppearCallback() const
326     {
327         if (onPageAppear_) {
328             onPageAppear_();
329         }
330     }
331 
FireDeclarativeOnPageDisAppearCallback()332     void FireDeclarativeOnPageDisAppearCallback() const
333     {
334         if (onPageDisAppear_) {
335             onPageDisAppear_();
336         }
337     }
338 
FireDeclarativeOnBackPressCallback()339     bool FireDeclarativeOnBackPressCallback() const
340     {
341         if (onBackPress_) {
342             return onBackPress_();
343         }
344         return false;
345     }
346 
FireDeclarativeOnPageRefreshCallback()347     void FireDeclarativeOnPageRefreshCallback() const
348     {
349         if (onPageRefresh_) {
350             onPageRefresh_();
351         }
352     }
353 
354     void OnJsEngineDestroy();
355 
356 private:
357     void SwapBackgroundDecoration(const RefPtr<PageTransitionComponent>& transition);
358     std::string GetCardId() const;
359 
360     bool pageCreated_ = false;
361     bool showCommandConsumed_ = false;
362     int32_t fragmentCount_ = 0;
363 
364     WeakPtr<PipelineContext> pipelineContext_;
365     RefPtr<PageTransitionComponent> pageTransition_;
366     RefPtr<Component> component_;
367     RefPtr<DOMDocument> domDoc_;
368     std::string url_;
369     WeakPtr<StageElement> container_;
370 
371     RefPtr<RevSourceMap> pageMap_;
372     RefPtr<RevSourceMap> appMap_;
373     bool useLiteStyle_ = false;
374     bool useBoxWrap_ = false;
375     bool usePluginComponent_ = false;
376     std::string pluginComponentJsonData_;
377 
378     std::vector<RefPtr<JsCommand>> jsCommands_;
379     std::vector<NodeId> dirtyNodesOrderedByTime_;
380     std::unordered_set<NodeId> dirtyNodes_;
381     std::mutex cmdMutex_;
382     std::vector<RefPtr<JsCommand>> showCommands_;
383     std::function<void(const RefPtr<JsAcePage>&)> flushCallback_;
384     std::string pageParams_;
385     std::mutex eventMutex_;
386     std::unordered_map<NodeId, std::unordered_map<std::string, std::string>> nodeEvent_;
387     std::mutex bridgeMutex_;
388     std::unordered_map<NodeId, RefPtr<BaseAnimationBridge>> animationBridges_;
389     std::unordered_map<NodeId, RefPtr<BaseCanvasBridge>> canvasBridges_;
390     std::unordered_map<int32_t, RefPtr<BaseCanvasBridge>> offscreenCanvasBridges_;
391     std::unordered_map<NodeId, RefPtr<BaseXComponentBridge>> xcomponentBridges_;
392     std::unordered_map<int32_t, RefPtr<BaseAnimationBridge>> animatorBridges_;
393     std::unordered_map<std::string, RefPtr<Curve>> curves_;
394     std::unordered_map<std::string, RefPtr<AnimatorInfo>> animatorInfos_;
395     std::shared_ptr<JsPageRadioGroups> radioGroups_;
396 
397     std::function<void()> onPageAppear_;
398     std::function<void()> onPageDisAppear_;
399     std::function<bool()> onBackPress_;
400     std::function<void()> onPageRefresh_;
401 };
402 
403 } // namespace OHOS::Ace::Framework
404 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_JS_ACE_PAGE_H
405