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