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_ENGINE_COMMON_JS_ENGINE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_COMMON_JS_ENGINE_H 18 19 #include <functional> 20 #include <set> 21 #include <string> 22 #include <memory> 23 #include <unordered_map> 24 25 #include "base/utils/macros.h" 26 #include "bridge/js_frontend/engine/jsi/js_value.h" 27 #include "core/common/frontend.h" 28 #include "core/common/js_message_dispatcher.h" 29 #include "frameworks/bridge/js_frontend/frontend_delegate.h" 30 31 class NativeEngine; 32 class NativeReference; 33 typedef struct napi_value__* napi_value; 34 35 namespace OHOS::Ace::Framework { 36 class JsAcePage; 37 using PixelMapNapiEntry = void* (*)(void*, void*); 38 struct JsModule { 39 const std::string moduleName; 40 const std::string methods; 41 }; 42 43 struct JsComponent { 44 const std::string componentName; 45 const std::string methods; 46 }; 47 48 // used for hybrid application 49 enum class JsEngineHybridType { 50 NONE, DYNAMIC_HYBRID_STATIC, STATIC_HYBRID_DYNAMIC 51 }; 52 53 class JsEngineInstance { 54 public: 55 JsEngineInstance() = default; 56 virtual ~JsEngineInstance() = default; 57 58 virtual void FlushCommandBuffer(void* context, const std::string& command); GetNativeEngine()59 NativeEngine* GetNativeEngine() 60 { 61 return nativeEngine_; 62 } SetNativeEngine(NativeEngine * nativeEngine)63 void SetNativeEngine(NativeEngine* nativeEngine) 64 { 65 nativeEngine_ = nativeEngine; 66 } 67 68 protected: 69 NativeEngine* nativeEngine_ = nullptr; 70 }; 71 72 using InspectorFunc = std::function<void()>; 73 class InspectorEvent : public virtual AceType { 74 DECLARE_ACE_TYPE(InspectorEvent, AceType); 75 public: InspectorEvent(InspectorFunc && callback)76 explicit InspectorEvent(InspectorFunc&& callback) : callback_(std::move(callback)) {} 77 ~InspectorEvent() override = default; 78 operator()79 void operator()() const 80 { 81 if (callback_) { 82 callback_(); 83 } 84 } 85 86 private: 87 InspectorFunc callback_; 88 }; 89 90 using PageUrlCheckFunc = std::function<void(const std::string&, const std::function<void()>&, 91 const std::function<void(int32_t, const std::string&)>&)>; 92 93 class ACE_FORCE_EXPORT JsEngine : public AceType { 94 DECLARE_ACE_TYPE(JsEngine, AceType); 95 96 public: 97 JsEngine() = default; 98 ~JsEngine() override = default; 99 100 void RegisterSingleComponent(std::string& command, const std::string& componentName, const std::string& methods); 101 102 void RegisterSingleModule(std::string& command, const std::string& moduleName, const std::string& methods); 103 104 void RegisterModules(std::string& command); 105 106 void RegisterComponents(std::string& command); 107 108 // Initialize the JS engine. 109 virtual bool Initialize(const RefPtr<FrontendDelegate>& delegate) = 0; 110 111 // Destroy the JS engine resource. Destroy()112 virtual void Destroy() {} 113 114 // Load script in JS engine, and execute in corresponding context. 115 virtual void LoadJs(const std::string& url, const RefPtr<JsAcePage>& page, bool isMainPage) = 0; 116 // Load ets card script in JS engine, and execute in corresponding context. 117 virtual bool LoadCard(const std::string& url, int64_t cardId, const std::string& entryPoint = "") 118 { 119 return false; 120 } 121 122 // Load the app.js file of the FA model in NG structure.. LoadFaAppSource()123 virtual bool LoadFaAppSource() 124 { 125 return false; 126 } 127 128 // Load the js file of the page in NG structure.. 129 virtual bool LoadPageSource( 130 const std::string& /* url */, const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) 131 { 132 return false; 133 } 134 135 virtual bool LoadPageSource( 136 const std::shared_ptr<std::vector<uint8_t>>& content, 137 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr, 138 const std::string& contentName = "") 139 { 140 return false; 141 } 142 LoadNamedRouterSource(const std::string & routeNameOrUrl,bool isNamedRoute)143 virtual bool LoadNamedRouterSource(const std::string& routeNameOrUrl, bool isNamedRoute) 144 { 145 return false; 146 } 147 GeneratePageByIntent(const std::string & bundleName,const std::string & moduleName,const std::string & pagePath)148 virtual bool GeneratePageByIntent( 149 const std::string& bundleName, const std::string& moduleName, const std::string& pagePath) 150 { 151 return false; 152 } 153 GetFullPathInfo()154 virtual std::unique_ptr<JsonValue> GetFullPathInfo() 155 { 156 return nullptr; 157 } 158 RestoreFullPathInfo(std::unique_ptr<JsonValue> namedRouterInfo)159 virtual void RestoreFullPathInfo(std::unique_ptr<JsonValue> namedRouterInfo) {} 160 GetNamedRouterInfo()161 virtual std::unique_ptr<JsonValue> GetNamedRouterInfo() 162 { 163 return nullptr; 164 } 165 RestoreNamedRouterInfo(std::unique_ptr<JsonValue> namedRouterInfo)166 virtual void RestoreNamedRouterInfo(std::unique_ptr<JsonValue> namedRouterInfo) {} 167 IsNamedRouterNeedPreload(const std::string & name)168 virtual bool IsNamedRouterNeedPreload(const std::string& name) 169 { 170 return false; 171 } 172 PreloadNamedRouter(const std::string & name,std::function<void (bool)> && loadFinishCallback)173 virtual void PreloadNamedRouter(const std::string& name, std::function<void(bool)>&& loadFinishCallback) {} 174 SetPageUrlCheckFunc(PageUrlCheckFunc && func)175 virtual void SetPageUrlCheckFunc(PageUrlCheckFunc&& func) 176 { 177 pageUrlCheckFunc_ = func; 178 } 179 SearchRouterRegisterMap(const std::string & pageName)180 virtual std::string SearchRouterRegisterMap(const std::string& pageName) 181 { 182 return ""; 183 } 184 LoadNavDestinationSource(const std::string & pageUrl,const std::string & bundleName,const std::string & moduleName,bool isSingleton)185 virtual int32_t LoadNavDestinationSource(const std::string& pageUrl, const std::string& bundleName, 186 const std::string& moduleName, bool isSingleton) 187 { 188 return false; 189 } 190 UpdateRootComponent()191 virtual bool UpdateRootComponent() 192 { 193 return false; 194 } 195 LoadPluginComponent(const std::string & url,const RefPtr<JsAcePage> & page,bool isMainPage)196 virtual bool LoadPluginComponent(const std::string &url, const RefPtr<JsAcePage>& page, bool isMainPage) 197 { 198 return false; 199 } 200 ExecuteJs(const uint8_t * content,int32_t size)201 virtual bool ExecuteJs(const uint8_t* content, int32_t size) 202 { 203 return false; 204 } 205 206 // Update running page 207 virtual void UpdateRunningPage(const RefPtr<JsAcePage>& page) = 0; 208 209 // Update staging page 210 virtual void UpdateStagingPage(const RefPtr<JsAcePage>& page) = 0; 211 212 // Reset loading page 213 virtual void ResetStagingPage() = 0; 214 215 virtual void SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& dispatcher) = 0; 216 217 // Fire AsyncEvent on JS 218 virtual void FireAsyncEvent(const std::string& eventId, const std::string& param) = 0; 219 220 // Fire SyncEvent on JS 221 virtual void FireSyncEvent(const std::string& eventId, const std::string& param) = 0; 222 223 // Fire external event on JS thread 224 virtual void FireExternalEvent(const std::string& componentId, uint32_t nodeId, bool isDestroy = false) = 0; 225 226 // Timer callback on JS 227 virtual void TimerCallback(const std::string& callbackId, const std::string& delay, bool isInterval) = 0; 228 229 // Destroy page instance on JS 230 virtual void DestroyPageInstance(int32_t pageId) = 0; 231 232 // destroy application instance according packageName 233 virtual void DestroyApplication(const std::string& packageName) = 0; 234 235 // update application State according packageName UpdateApplicationState(const std::string & packageName,Frontend::State state)236 virtual void UpdateApplicationState(const std::string& packageName, Frontend::State state) {} 237 OnWindowDisplayModeChanged(bool isShownInMultiWindow,const std::string & data)238 virtual void OnWindowDisplayModeChanged(bool isShownInMultiWindow, const std::string& data) {} 239 OnNewWant(const std::string & data)240 virtual void OnNewWant(const std::string& data) {} 241 OnSaveAbilityState(std::string & data)242 virtual void OnSaveAbilityState(std::string& data) {} 243 OnRestoreAbilityState(const std::string & data)244 virtual void OnRestoreAbilityState(const std::string& data) {} 245 OnConfigurationUpdated(const std::string & data)246 virtual void OnConfigurationUpdated(const std::string& data) {} 247 OnActive()248 virtual void OnActive() {} 249 OnInactive()250 virtual void OnInactive() {} 251 OnMemoryLevel(const int32_t code)252 virtual void OnMemoryLevel(const int32_t code) {} 253 OnStartContinuation()254 virtual bool OnStartContinuation() 255 { 256 return false; 257 } 258 OnCompleteContinuation(int32_t code)259 virtual void OnCompleteContinuation(int32_t code) {} 260 OnRemoteTerminated()261 virtual void OnRemoteTerminated() {} 262 OnSaveData(std::string & data)263 virtual void OnSaveData(std::string& data) {} 264 OnRestoreData(const std::string & data)265 virtual bool OnRestoreData(const std::string& data) 266 { 267 return false; 268 } 269 MediaQueryCallback(const std::string & callbackId,const std::string & args)270 virtual void MediaQueryCallback(const std::string& callbackId, const std::string& args) 271 { 272 if (mediaUpdateCallback_) { 273 mediaUpdateCallback_(this); 274 } 275 } 276 LayoutInspectorCallback(const std::string & componentId)277 void LayoutInspectorCallback(const std::string& componentId) 278 { 279 auto iter = layoutEvents_.find(componentId); 280 if (iter != layoutEvents_.end()) { 281 for (auto&& observer : iter->second) { 282 (*observer)(); 283 } 284 } 285 } 286 DrawInspectorCallback(const std::string & componentId)287 void DrawInspectorCallback(const std::string& componentId) 288 { 289 auto iter = drawEvents_.find(componentId); 290 if (iter != drawEvents_.end()) { 291 for (auto&& observer : iter->second) { 292 (*observer)(); 293 } 294 } 295 } 296 DrawChildrenInspectorCallback(const std::string & componentId)297 void DrawChildrenInspectorCallback(const std::string& componentId) 298 { 299 auto iter = drawChildrenEvents_.find(componentId); 300 if (iter != drawChildrenEvents_.end()) { 301 for (auto&& observer : iter->second) { 302 (*observer)(); 303 } 304 } 305 } 306 307 virtual void RequestAnimationCallback(const std::string& callbackId, uint64_t timeStamp) = 0; 308 309 virtual void JsCallback(const std::string& callbackId, const std::string& args) = 0; 310 SetErrorEventHandler(std::function<void (const std::string &,const std::string &)> && errorCallback)311 virtual void SetErrorEventHandler(std::function<void(const std::string&, const std::string&)>&& errorCallback) {} 312 313 virtual void RunGarbageCollection() = 0; 314 RunFullGarbageCollection()315 virtual void RunFullGarbageCollection() {} 316 DumpHeapSnapshot(bool isPrivate)317 virtual void DumpHeapSnapshot(bool isPrivate) {} 318 DestroyHeapProfiler()319 virtual void DestroyHeapProfiler() {} 320 ForceFullGC()321 virtual void ForceFullGC() {} 322 NotifyUIIdle()323 virtual void NotifyUIIdle() {} 324 GetStacktraceMessage()325 virtual std::string GetStacktraceMessage() 326 { 327 return ""; 328 } 329 GetStackTrace(std::string & trace)330 virtual void GetStackTrace(std::string& trace) {} 331 NotifyAppStorage(const std::string & key,const std::string & value)332 virtual void NotifyAppStorage(const std::string& key, const std::string& value) {} 333 334 virtual RefPtr<GroupJsBridge> GetGroupJsBridge() = 0; 335 GetFrontend()336 virtual ACE_EXPORT RefPtr<FrontendDelegate> GetFrontend() 337 { 338 return nullptr; 339 } 340 SetLocalStorage(int32_t instanceId,NativeReference * storage)341 virtual void SetLocalStorage(int32_t instanceId, NativeReference* storage) {} 342 SetContext(int32_t instanceId,NativeReference * context)343 virtual void SetContext(int32_t instanceId, NativeReference* context) {} 344 GetJsContext()345 virtual std::shared_ptr<Framework::JsValue> GetJsContext() { return nullptr; } 346 SetJsContext(const std::shared_ptr<Framework::JsValue> & jsContext)347 virtual void SetJsContext(const std::shared_ptr<Framework::JsValue>& jsContext) {} 348 SerializeValue(const std::shared_ptr<Framework::JsValue> & jsValue)349 virtual std::shared_ptr<void> SerializeValue( 350 const std::shared_ptr<Framework::JsValue>& jsValue) { return nullptr; } 351 TriggerModuleSerializer()352 virtual void TriggerModuleSerializer() {} 353 SetJsContextWithDeserialize(const std::shared_ptr<void> & recoder)354 virtual void SetJsContextWithDeserialize(const std::shared_ptr<void>& recoder) {} 355 SetPkgNameList(const std::map<std::string,std::string> & map)356 virtual void SetPkgNameList(const std::map<std::string, std::string>& map) {} 357 SetPkgAliasList(const std::map<std::string,std::string> & map)358 virtual void SetPkgAliasList(const std::map<std::string, std::string>& map) {} 359 SetpkgContextInfoList(const std::map<std::string,std::vector<std::vector<std::string>>> & map)360 virtual void SetpkgContextInfoList(const std::map<std::string, std::vector<std::vector<std::string>>>& map) {} 361 IsDebugVersion()362 bool IsDebugVersion() const 363 { 364 return isDebugVersion_; 365 } 366 SetDebugVersion(bool value)367 void SetDebugVersion(bool value) 368 { 369 isDebugVersion_ = value; 370 } 371 NeedDebugBreakPoint()372 bool NeedDebugBreakPoint() const 373 { 374 return needDebugBreakPoint_; 375 } 376 SetNeedDebugBreakPoint(bool value)377 void SetNeedDebugBreakPoint(bool value) 378 { 379 needDebugBreakPoint_ = value; 380 } 381 GetInstanceName()382 const std::string& GetInstanceName() const 383 { 384 return instanceName_; 385 } 386 SetInstanceName(const std::string & name)387 void SetInstanceName(const std::string& name) 388 { 389 instanceName_ = name; 390 } 391 AddExtraNativeObject(const std::string & key,void * value)392 void AddExtraNativeObject(const std::string& key, void* value) 393 { 394 extraNativeObject_[key] = value; 395 } 396 GetExtraNativeObject()397 const std::unordered_map<std::string, void*>& GetExtraNativeObject() const 398 { 399 return extraNativeObject_; 400 } 401 SetForceUpdate(bool needUpdate)402 void SetForceUpdate(bool needUpdate) 403 { 404 needUpdate_ = needUpdate; 405 } 406 GetNativeEngine()407 NativeEngine* GetNativeEngine() 408 { 409 return nativeEngine_; 410 } 411 RegisterMediaUpdateCallback(std::function<void (JsEngine *)> cb)412 void ACE_EXPORT RegisterMediaUpdateCallback(std::function<void(JsEngine*)> cb) 413 { 414 mediaUpdateCallback_ = std::move(cb); 415 } 416 UnregisterMediaUpdateCallback()417 void ACE_EXPORT UnregisterMediaUpdateCallback() 418 { 419 mediaUpdateCallback_ = nullptr; 420 } 421 RegisterLayoutInspectorCallback(const RefPtr<InspectorEvent> & layoutEvent,const std::string & componentId)422 void ACE_EXPORT RegisterLayoutInspectorCallback( 423 const RefPtr<InspectorEvent>& layoutEvent, const std::string& componentId) 424 { 425 layoutEvents_[componentId].emplace(layoutEvent); 426 } 427 UnregisterLayoutInspectorCallback(const RefPtr<InspectorEvent> & layoutEvent,const std::string & componentId)428 void ACE_EXPORT UnregisterLayoutInspectorCallback( 429 const RefPtr<InspectorEvent>& layoutEvent, const std::string& componentId) 430 { 431 auto iter = layoutEvents_.find(componentId); 432 if (iter != layoutEvents_.end()) { 433 iter->second.erase(layoutEvent); 434 if (iter->second.empty()) { 435 layoutEvents_.erase(componentId); 436 } 437 } 438 } 439 RegisterDrawInspectorCallback(const RefPtr<InspectorEvent> & drawEvent,const std::string & componentId)440 void ACE_EXPORT RegisterDrawInspectorCallback( 441 const RefPtr<InspectorEvent>& drawEvent, const std::string& componentId) 442 { 443 drawEvents_[componentId].emplace(drawEvent); 444 } 445 UnregisterDrawInspectorCallback(const RefPtr<InspectorEvent> & drawEvent,const std::string & componentId)446 void ACE_EXPORT UnregisterDrawInspectorCallback( 447 const RefPtr<InspectorEvent>& drawEvent, const std::string& componentId) 448 { 449 auto iter = drawEvents_.find(componentId); 450 if (iter != drawEvents_.end()) { 451 iter->second.erase(drawEvent); 452 if (iter->second.empty()) { 453 drawEvents_.erase(componentId); 454 } 455 } 456 } 457 RegisterDrawChildrenInspectorCallback(const RefPtr<InspectorEvent> & drawChildrenEvent,const std::string & componentId)458 void ACE_EXPORT RegisterDrawChildrenInspectorCallback( 459 const RefPtr<InspectorEvent>& drawChildrenEvent, const std::string& componentId) 460 { 461 if (drawChildrenEvent) { 462 drawChildrenEvents_[componentId].emplace(drawChildrenEvent); 463 } 464 } 465 UnregisterDrawChildrenInspectorCallback(const RefPtr<InspectorEvent> & drawChildrenEvent,const std::string & componentId)466 void ACE_EXPORT UnregisterDrawChildrenInspectorCallback( 467 const RefPtr<InspectorEvent>& drawChildrenEvent, const std::string& componentId) 468 { 469 if (!drawChildrenEvent) { 470 return; 471 } 472 auto iter = drawChildrenEvents_.find(componentId); 473 if (iter != drawChildrenEvents_.end()) { 474 iter->second.erase(drawChildrenEvent); 475 if (iter->second.empty()) { 476 drawChildrenEvents_.erase(componentId); 477 } 478 } 479 } 480 IsLayoutCallBackFuncExist(const std::string & componentId)481 bool IsLayoutCallBackFuncExist(const std::string& componentId) const 482 { 483 if (layoutEvents_.find(componentId) != layoutEvents_.end()) { 484 return true; 485 } 486 return false; 487 } 488 IsDrawCallBackFuncExist(const std::string & componentId)489 bool IsDrawCallBackFuncExist(const std::string& componentId) const 490 { 491 if (drawEvents_.find(componentId) != drawEvents_.end()) { 492 return true; 493 } 494 return false; 495 } 496 IsDrawChildrenCallbackFuncExist(const std::string & componentId)497 bool IsDrawChildrenCallbackFuncExist(const std::string& componentId) const 498 { 499 return drawChildrenEvents_.find(componentId) != drawChildrenEvents_.end(); 500 } 501 502 virtual void RunNativeEngineLoop(); 503 SetPluginBundleName(const std::string & pluginBundleName)504 virtual void SetPluginBundleName(const std::string& pluginBundleName) {} 505 SetPluginModuleName(const std::string & pluginModuleName)506 virtual void SetPluginModuleName(const std::string& pluginModuleName) {} 507 508 #if !defined(PREVIEW) 509 static PixelMapNapiEntry GetPixelMapNapiEntry(); 510 #endif 511 #if defined(PREVIEW) GetNewComponentWithJsCode(const std::string & jsCode,const std::string & viewID)512 virtual RefPtr<Component> GetNewComponentWithJsCode(const std::string& jsCode, const std::string& viewID) 513 { 514 return nullptr; 515 } 516 ExecuteJsForFastPreview(const std::string & jsCode,const std::string & viewID)517 virtual bool ExecuteJsForFastPreview(const std::string& jsCode, const std::string& viewID) 518 { 519 return true; 520 } 521 ReplaceJSContent(const std::string & url,const std::string componentName)522 virtual void ReplaceJSContent(const std::string& url, const std::string componentName) 523 { 524 LOGE("Ark does not support replaceJSContent"); 525 return; 526 } 527 InitializeModuleSearcher(const std::string & bundleName,const std::string & moduleName,const std::string assetPath,bool isBundle)528 virtual void InitializeModuleSearcher( 529 const std::string& bundleName, const std::string& moduleName, const std::string assetPath, bool isBundle) 530 { 531 LOGE("Ark does not support InitializeModuleSearcher"); 532 } 533 IsComponentPreview()534 virtual bool IsComponentPreview() 535 { 536 return false; 537 } 538 #endif FlushReload()539 virtual void FlushReload() {} GetContextValue()540 virtual napi_value GetContextValue() 541 { 542 napi_value value = nullptr; 543 return value; 544 } 545 BuilderNodeFunc(std::string functionName,const std::vector<int32_t> & nodeIds)546 virtual bool BuilderNodeFunc(std::string functionName, const std::vector<int32_t>& nodeIds) 547 { 548 return false; 549 } 550 GetFrameNodeValueByNodeId(int32_t nodeId)551 virtual napi_value GetFrameNodeValueByNodeId(int32_t nodeId) 552 { 553 return nullptr; 554 } 555 UpdateHybridType(JsEngineHybridType type)556 void UpdateHybridType(JsEngineHybridType type) 557 { 558 hybridType = type; 559 } 560 561 protected: 562 NativeEngine* nativeEngine_ = nullptr; 563 std::function<void(JsEngine*)> mediaUpdateCallback_; 564 std::map<std::string, std::set<RefPtr<InspectorEvent>>> layoutEvents_; 565 std::map<std::string, std::set<RefPtr<InspectorEvent>>> drawEvents_; 566 std::map<std::string, std::set<RefPtr<InspectorEvent>>> drawChildrenEvents_; 567 bool needUpdate_ = false; 568 PageUrlCheckFunc pageUrlCheckFunc_; 569 JsEngineHybridType hybridType = JsEngineHybridType::NONE; 570 571 private: 572 // weather the app has debugger.so. 573 bool isDebugVersion_ = false; 574 575 // if debug, '-D' means need debug breakpoint, by default, do not enter breakpoint. 576 bool needDebugBreakPoint_ = false; 577 578 std::string instanceName_; 579 580 std::unordered_map<std::string, void*> extraNativeObject_; 581 }; 582 } // namespace OHOS::Ace::Framework 583 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_COMMON_JS_ENGINE_H 584