• 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 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