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