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