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