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 { 127 return false; 128 } 129 LoadNamedRouterSource(const std::string & namedRoute,bool isTriggeredByJs)130 virtual bool LoadNamedRouterSource(const std::string& namedRoute, bool isTriggeredByJs) 131 { 132 return false; 133 } 134 SearchRouterRegisterMap(const std::string & pageName)135 virtual std::string SearchRouterRegisterMap(const std::string& pageName) 136 { 137 return ""; 138 } 139 UpdateRootComponent()140 virtual bool UpdateRootComponent() 141 { 142 return false; 143 } 144 LoadPluginComponent(const std::string & url,const RefPtr<JsAcePage> & page,bool isMainPage)145 virtual bool LoadPluginComponent(const std::string &url, const RefPtr<JsAcePage>& page, bool isMainPage) 146 { 147 return false; 148 } 149 ExecuteJs(const uint8_t * content,int32_t size)150 virtual bool ExecuteJs(const uint8_t* content, int32_t size) 151 { 152 return false; 153 } 154 155 // Update running page 156 virtual void UpdateRunningPage(const RefPtr<JsAcePage>& page) = 0; 157 158 // Update staging page 159 virtual void UpdateStagingPage(const RefPtr<JsAcePage>& page) = 0; 160 161 // Reset loading page 162 virtual void ResetStagingPage() = 0; 163 164 virtual void SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& dispatcher) = 0; 165 166 // Fire AsyncEvent on JS 167 virtual void FireAsyncEvent(const std::string& eventId, const std::string& param) = 0; 168 169 // Fire SyncEvent on JS 170 virtual void FireSyncEvent(const std::string& eventId, const std::string& param) = 0; 171 172 // Fire external event on JS thread 173 virtual void FireExternalEvent(const std::string& componentId, uint32_t nodeId, bool isDestroy = false) = 0; 174 175 // Timer callback on JS 176 virtual void TimerCallback(const std::string& callbackId, const std::string& delay, bool isInterval) = 0; 177 178 // Destroy page instance on JS 179 virtual void DestroyPageInstance(int32_t pageId) = 0; 180 181 // destroy application instance according packageName 182 virtual void DestroyApplication(const std::string& packageName) = 0; 183 184 // update application State according packageName UpdateApplicationState(const std::string & packageName,Frontend::State state)185 virtual void UpdateApplicationState(const std::string& packageName, Frontend::State state) {} 186 OnWindowDisplayModeChanged(bool isShownInMultiWindow,const std::string & data)187 virtual void OnWindowDisplayModeChanged(bool isShownInMultiWindow, const std::string& data) {} 188 OnNewWant(const std::string & data)189 virtual void OnNewWant(const std::string& data) {} 190 OnSaveAbilityState(std::string & data)191 virtual void OnSaveAbilityState(std::string& data) {} 192 OnRestoreAbilityState(const std::string & data)193 virtual void OnRestoreAbilityState(const std::string& data) {} 194 OnConfigurationUpdated(const std::string & data)195 virtual void OnConfigurationUpdated(const std::string& data) {} 196 OnActive()197 virtual void OnActive() {} 198 OnInactive()199 virtual void OnInactive() {} 200 OnMemoryLevel(const int32_t code)201 virtual void OnMemoryLevel(const int32_t code) {} 202 OnStartContinuation()203 virtual bool OnStartContinuation() 204 { 205 return false; 206 } 207 OnCompleteContinuation(int32_t code)208 virtual void OnCompleteContinuation(int32_t code) {} 209 OnRemoteTerminated()210 virtual void OnRemoteTerminated() {} 211 OnSaveData(std::string & data)212 virtual void OnSaveData(std::string& data) {} 213 OnRestoreData(const std::string & data)214 virtual bool OnRestoreData(const std::string& data) 215 { 216 return false; 217 } 218 MediaQueryCallback(const std::string & callbackId,const std::string & args)219 virtual void MediaQueryCallback(const std::string& callbackId, const std::string& args) 220 { 221 if (mediaUpdateCallback_) { 222 mediaUpdateCallback_(this); 223 } 224 } 225 LayoutInspectorCallback(const std::string & componentId)226 void LayoutInspectorCallback(const std::string& componentId) 227 { 228 auto iter = layoutEvents_.find(componentId); 229 if (iter != layoutEvents_.end()) { 230 for (auto&& observer : iter->second) { 231 (*observer)(); 232 } 233 } 234 } 235 DrawInspectorCallback(const std::string & componentId)236 void DrawInspectorCallback(const std::string& componentId) 237 { 238 auto iter = drawEvents_.find(componentId); 239 if (iter != drawEvents_.end()) { 240 for (auto&& observer : iter->second) { 241 (*observer)(); 242 } 243 } 244 } 245 246 virtual void RequestAnimationCallback(const std::string& callbackId, uint64_t timeStamp) = 0; 247 248 virtual void JsCallback(const std::string& callbackId, const std::string& args) = 0; 249 SetErrorEventHandler(std::function<void (const std::string &,const std::string &)> && errorCallback)250 virtual void SetErrorEventHandler(std::function<void(const std::string&, const std::string&)>&& errorCallback) {} 251 252 virtual void RunGarbageCollection() = 0; 253 RunFullGarbageCollection()254 virtual void RunFullGarbageCollection() {} 255 DumpHeapSnapshot(bool isPrivate)256 virtual void DumpHeapSnapshot(bool isPrivate) {} 257 DestroyHeapProfiler()258 virtual void DestroyHeapProfiler() {} 259 ForceFullGC()260 virtual void ForceFullGC() {} 261 GetStacktraceMessage()262 virtual std::string GetStacktraceMessage() 263 { 264 return ""; 265 } 266 GetStackTrace(std::string & trace)267 virtual void GetStackTrace(std::string& trace) {} 268 NotifyAppStorage(const std::string & key,const std::string & value)269 virtual void NotifyAppStorage(const std::string& key, const std::string& value) {} 270 271 virtual RefPtr<GroupJsBridge> GetGroupJsBridge() = 0; 272 GetFrontend()273 virtual ACE_EXPORT RefPtr<FrontendDelegate> GetFrontend() 274 { 275 return nullptr; 276 } 277 SetLocalStorage(int32_t instanceId,NativeReference * storage)278 virtual void SetLocalStorage(int32_t instanceId, NativeReference* storage) {} 279 SetContext(int32_t instanceId,NativeReference * context)280 virtual void SetContext(int32_t instanceId, NativeReference* context) {} 281 IsDebugVersion()282 bool IsDebugVersion() const 283 { 284 return isDebugVersion_; 285 } 286 SetDebugVersion(bool value)287 void SetDebugVersion(bool value) 288 { 289 isDebugVersion_ = value; 290 } 291 NeedDebugBreakPoint()292 bool NeedDebugBreakPoint() const 293 { 294 return needDebugBreakPoint_; 295 } 296 SetNeedDebugBreakPoint(bool value)297 void SetNeedDebugBreakPoint(bool value) 298 { 299 needDebugBreakPoint_ = value; 300 } 301 GetInstanceName()302 const std::string& GetInstanceName() const 303 { 304 return instanceName_; 305 } 306 SetInstanceName(const std::string & name)307 void SetInstanceName(const std::string& name) 308 { 309 instanceName_ = name; 310 } 311 AddExtraNativeObject(const std::string & key,void * value)312 void AddExtraNativeObject(const std::string& key, void* value) 313 { 314 extraNativeObject_[key] = value; 315 } 316 GetExtraNativeObject()317 const std::unordered_map<std::string, void*>& GetExtraNativeObject() const 318 { 319 return extraNativeObject_; 320 } 321 SetForceUpdate(bool needUpdate)322 void SetForceUpdate(bool needUpdate) 323 { 324 needUpdate_ = needUpdate; 325 } 326 GetNativeEngine()327 NativeEngine* GetNativeEngine() 328 { 329 return nativeEngine_; 330 } 331 RegisterMediaUpdateCallback(std::function<void (JsEngine *)> cb)332 void ACE_EXPORT RegisterMediaUpdateCallback(std::function<void(JsEngine*)> cb) 333 { 334 mediaUpdateCallback_ = std::move(cb); 335 } 336 UnregisterMediaUpdateCallback()337 void ACE_EXPORT UnregisterMediaUpdateCallback() 338 { 339 mediaUpdateCallback_ = nullptr; 340 } 341 RegisterLayoutInspectorCallback(const RefPtr<InspectorEvent> & layoutEvent,const std::string & componentId)342 void ACE_EXPORT RegisterLayoutInspectorCallback( 343 const RefPtr<InspectorEvent>& layoutEvent, const std::string& componentId) 344 { 345 layoutEvents_[componentId].emplace(layoutEvent); 346 } 347 UnregisterLayoutInspectorCallback(const RefPtr<InspectorEvent> & layoutEvent,const std::string & componentId)348 void ACE_EXPORT UnregisterLayoutInspectorCallback( 349 const RefPtr<InspectorEvent>& layoutEvent, const std::string& componentId) 350 { 351 auto iter = layoutEvents_.find(componentId); 352 if (iter != layoutEvents_.end()) { 353 iter->second.erase(layoutEvent); 354 if (iter->second.empty()) { 355 layoutEvents_.erase(componentId); 356 } 357 } 358 } 359 RegisterDrawInspectorCallback(const RefPtr<InspectorEvent> & drawEvent,const std::string & componentId)360 void ACE_EXPORT RegisterDrawInspectorCallback( 361 const RefPtr<InspectorEvent>& drawEvent, const std::string& componentId) 362 { 363 drawEvents_[componentId].emplace(drawEvent); 364 } 365 UnregisterDrawInspectorCallback(const RefPtr<InspectorEvent> & drawEvent,const std::string & componentId)366 void ACE_EXPORT UnregisterDrawInspectorCallback( 367 const RefPtr<InspectorEvent>& drawEvent, const std::string& componentId) 368 { 369 auto iter = drawEvents_.find(componentId); 370 if (iter != drawEvents_.end()) { 371 iter->second.erase(drawEvent); 372 if (iter->second.empty()) { 373 drawEvents_.erase(componentId); 374 } 375 } 376 } 377 378 virtual void RunNativeEngineLoop(); 379 SetPluginBundleName(const std::string & pluginBundleName)380 virtual void SetPluginBundleName(const std::string& pluginBundleName) {} 381 SetPluginModuleName(const std::string & pluginModuleName)382 virtual void SetPluginModuleName(const std::string& pluginModuleName) {} 383 384 #if !defined(PREVIEW) 385 static PixelMapNapiEntry GetPixelMapNapiEntry(); 386 #endif 387 #if defined(PREVIEW) GetNewComponentWithJsCode(const std::string & jsCode,const std::string & viewID)388 virtual RefPtr<Component> GetNewComponentWithJsCode(const std::string& jsCode, const std::string& viewID) 389 { 390 return nullptr; 391 } 392 ExecuteJsForFastPreview(const std::string & jsCode,const std::string & viewID)393 virtual bool ExecuteJsForFastPreview(const std::string& jsCode, const std::string& viewID) 394 { 395 return true; 396 } 397 ReplaceJSContent(const std::string & url,const std::string componentName)398 virtual void ReplaceJSContent(const std::string& url, const std::string componentName) 399 { 400 LOGE("Ark does not support replaceJSContent"); 401 return; 402 } 403 InitializeModuleSearcher(const std::string & bundleName,const std::string & moduleName,const std::string assetPath,bool isBundle)404 virtual void InitializeModuleSearcher( 405 const std::string& bundleName, const std::string& moduleName, const std::string assetPath, bool isBundle) 406 { 407 LOGE("Ark does not support InitializeModuleSearcher"); 408 } 409 IsComponentPreview()410 virtual bool IsComponentPreview() 411 { 412 return false; 413 } 414 #endif FlushReload()415 virtual void FlushReload() {} GetContextValue()416 virtual napi_value GetContextValue() 417 { 418 napi_value value = nullptr; 419 return value; 420 } 421 422 protected: 423 NativeEngine* nativeEngine_ = nullptr; 424 std::function<void(JsEngine*)> mediaUpdateCallback_; 425 std::map<std::string, std::set<RefPtr<InspectorEvent>>> layoutEvents_; 426 std::map<std::string, std::set<RefPtr<InspectorEvent>>> drawEvents_; 427 bool needUpdate_ = false; 428 429 private: 430 // weather the app has debugger.so. 431 bool isDebugVersion_ = false; 432 433 // if debug, '-D' means need debug breakpoint, by default, do not enter breakpoint. 434 bool needDebugBreakPoint_ = false; 435 436 std::string instanceName_; 437 438 std::unordered_map<std::string, void*> extraNativeObject_; 439 }; 440 } // namespace OHOS::Ace::Framework 441 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_ENGINE_COMMON_JS_ENGINE_H 442