• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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