• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_FRONTEND_DELEGATE_IMPL_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_FRONTEND_DELEGATE_IMPL_H
18 
19 #include <future>
20 #include <mutex>
21 #include <unordered_map>
22 
23 #include "base/memory/ace_type.h"
24 #include "base/thread/cancelable_callback.h"
25 #include "core/common/frontend.h"
26 #include "core/common/js_message_dispatcher.h"
27 #include "core/components/dialog/dialog_component.h"
28 #include "core/pipeline/pipeline_context.h"
29 #include "frameworks/bridge/common/accessibility/accessibility_node_manager.h"
30 #include "frameworks/bridge/common/manifest/manifest_parser.h"
31 #include "frameworks/bridge/js_frontend/engine/common/group_js_bridge.h"
32 #include "frameworks/bridge/js_frontend/frontend_delegate.h"
33 #include "frameworks/bridge/js_frontend/js_ace_page.h"
34 
35 namespace OHOS::Ace::Framework {
36 
37 using LoadJsCallback = std::function<void(const std::string&, const RefPtr<JsAcePage>&, bool isMainPage)>;
38 using JsMessageDispatcherSetterCallback = std::function<void(const RefPtr<JsMessageDispatcher>&)>;
39 using EventCallback = std::function<void(const std::string&, const std::string&)>;
40 using ExternalEventCallback = std::function<void(const std::string&, const uint32_t&)>;
41 using UpdatePageCallback = std::function<void(const RefPtr<JsAcePage>&)>;
42 using ResetStagingPageCallback = std::function<void()>;
43 using MediaQueryCallback = std::function<void(const std::string& callbackId, const std::string& args)>;
44 using DestroyPageCallback = std::function<void(int32_t pageId)>;
45 using DestroyApplicationCallback = std::function<void(const std::string& packageName)>;
46 using UpdateApplicationStateCallback = std::function<void(const std::string& packageName, Frontend::State state)>;
47 using TimerCallback = std::function<void(const std::string& callbackId, const std::string& delay, bool isInterval)>;
48 using RequestAnimationCallback = std::function<void(const std::string& callbackId, uint64_t timeStamp)>;
49 using JsCallback = std::function<void(const std::string& callbackId, const std::string& args)>;
50 using OnWindowDisplayModeChangedCallBack = std::function<void(bool isShownInMultiWindow, const std::string& data)>;
51 using OnConfigurationUpdatedCallBack = std::function<void(const std::string& data)>;
52 using OnNewWantCallBack = std::function<void(const std::string& data)>;
53 using OnSaveAbilityStateCallBack = std::function<void(std::string& data)>;
54 using OnRestoreAbilityStateCallBack = std::function<void(const std::string& data)>;
55 using OnActiveCallBack = std::function<void()>;
56 using OnInactiveCallBack = std::function<void()>;
57 using OnMemoryLevelCallBack = std::function<void(const int32_t level)>;
58 using OnStartContinuationCallBack = std::function<bool(void)>;
59 using OnCompleteContinuationCallBack = std::function<void(int32_t code)>;
60 using OnRemoteTerminatedCallBack = std::function<void(void)>;
61 using OnSaveDataCallBack = std::function<void(std::string& data)>;
62 using OnRestoreDataCallBack = std::function<bool(const std::string& data)>;
63 using CallNativeHandlerCallback = std::function<void(const std::string& event, const std::string& params)>;
64 
65 struct PageInfo {
66     int32_t pageId = -1;
67     std::string url;
68     bool isRestore = false;
69     std::function<void(int32_t)> alertCallback;
70     DialogProperties dialogProperties;
71 };
72 
73 class PipelineContextHolder {
74 public:
~PipelineContextHolder()75     ~PipelineContextHolder()
76     {
77         if (pipelineContext_) {
78             auto taskExecutor = pipelineContext_->GetTaskExecutor();
79             // To guarantee the pipelineContext_ destruct in platform thread
80             auto context = AceType::RawPtr(pipelineContext_);
81             context->IncRefCount();
82             pipelineContext_.Reset();
83             taskExecutor->PostTask([context] { context->DecRefCount(); }, TaskExecutor::TaskType::PLATFORM);
84         }
85     }
86 
Attach(const RefPtr<PipelineContext> & context)87     void Attach(const RefPtr<PipelineContext>& context)
88     {
89         if (attached_ || !context) {
90             return;
91         }
92 
93         attached_ = true;
94         promise_.set_value(context);
95     }
96 
Get()97     const RefPtr<PipelineContext>& Get()
98     {
99         if (!pipelineContext_) {
100             pipelineContext_ = future_.get();
101             ACE_DCHECK(pipelineContext_);
102         }
103         return pipelineContext_;
104     }
105 
106 private:
107     bool attached_ = false;
108     std::promise<RefPtr<PipelineContext>> promise_;
109     std::future<RefPtr<PipelineContext>> future_ = promise_.get_future();
110     RefPtr<PipelineContext> pipelineContext_;
111 };
112 
113 struct FrontendDelegateImplBuilder {
114     RefPtr<TaskExecutor> taskExecutor;
115     LoadJsCallback loadCallback;
116     JsMessageDispatcherSetterCallback transferCallback;
117     EventCallback asyncEventCallback;
118     EventCallback syncEventCallback;
119     ExternalEventCallback externalEventCallback;
120     UpdatePageCallback updatePageCallback;
121     ResetStagingPageCallback resetStagingPageCallback;
122     DestroyPageCallback destroyPageCallback;
123     DestroyApplicationCallback destroyApplicationCallback;
124     UpdateApplicationStateCallback updateApplicationStateCallback;
125     OnStartContinuationCallBack onStartContinuationCallBack;
126     OnCompleteContinuationCallBack onCompleteContinuationCallBack;
127     OnRemoteTerminatedCallBack onRemoteTerminatedCallBack;
128     OnSaveDataCallBack onSaveDataCallBack;
129     OnRestoreDataCallBack onRestoreDataCallBack;
130     TimerCallback timerCallback;
131     MediaQueryCallback mediaQueryCallback;
132     RequestAnimationCallback requestAnimationCallback;
133     JsCallback jsCallback;
134     OnWindowDisplayModeChangedCallBack onWindowDisplayModeChangedCallBack;
135     OnNewWantCallBack onNewWantCallBack;
136     OnSaveAbilityStateCallBack onSaveAbilityStateCallBack;
137     OnRestoreAbilityStateCallBack onRestoreAbilityStateCallBack;
138     OnActiveCallBack onActiveCallBack;
139     OnInactiveCallBack onInactiveCallBack;
140     OnMemoryLevelCallBack onMemoryLevelCallBack;
141     CallNativeHandlerCallback callNativeHandler;
142     void* ability;
143 };
144 
145 class DelegateClient {
146 public:
147     using RouterPushCallback = std::function<void(const std::string& url)>;
148     using GetWebPageUrlCallback = std::function<void(std::string& url, int32_t& id)>;
149     using IsPagePathInvalidCallback = std::function<void(bool& isPageInvalid)>;
150     DelegateClient &operator = (const DelegateClient &) = delete;
151     DelegateClient(const DelegateClient &) = delete;
152     ~DelegateClient() = default;
153 
GetInstance()154     static DelegateClient& GetInstance()
155     {
156         static DelegateClient instance;
157         return instance;
158     }
159 
RegisterRouterPushCallback(RouterPushCallback && callback)160     void RegisterRouterPushCallback(RouterPushCallback &&callback)
161     {
162         routerPushCallback_ = callback;
163     }
164 
RouterPush(const std::string & url)165     void RouterPush(const std::string& url)
166     {
167         if (routerPushCallback_) {
168             return routerPushCallback_(url);
169         }
170     }
171 
RegisterGetWebPageUrlCallback(GetWebPageUrlCallback && callback)172     void RegisterGetWebPageUrlCallback(GetWebPageUrlCallback &&callback)
173     {
174         getWebPageUrlCallback_ = callback;
175     }
176 
GetWebPageUrl(std::string & pageUrl,int32_t & pageId)177     void GetWebPageUrl(std::string& pageUrl, int32_t& pageId)
178     {
179         if (getWebPageUrlCallback_) {
180             return getWebPageUrlCallback_(pageUrl, pageId);
181         }
182     }
183 
RegisterIsPagePathInvalidCallback(IsPagePathInvalidCallback && callback)184     void RegisterIsPagePathInvalidCallback(IsPagePathInvalidCallback &&callback)
185     {
186         isPagePathInvalidCallback_ = callback;
187     }
188 
GetIsPagePathInvalid(bool & isPageInvalid)189     void GetIsPagePathInvalid(bool& isPageInvalid)
190     {
191         if (isPagePathInvalidCallback_) {
192             return isPagePathInvalidCallback_(isPageInvalid);
193         }
194     }
195 
196 private:
197     DelegateClient() = default;
198     RouterPushCallback routerPushCallback_;
199     GetWebPageUrlCallback getWebPageUrlCallback_;
200     IsPagePathInvalidCallback isPagePathInvalidCallback_;
201 };
202 
203 class FrontendDelegateImpl : public FrontendDelegate {
204     DECLARE_ACE_TYPE(FrontendDelegateImpl, FrontendDelegate);
205 
206 public:
207     explicit FrontendDelegateImpl(const FrontendDelegateImplBuilder& builder);
208     ~FrontendDelegateImpl() override;
209 
210     void AttachPipelineContext(const RefPtr<PipelineContext>& context) override;
211 
212     // JsFrontend delegate functions.
213     void RunPage(const std::string& url, const std::string& params);
214     void SetJsMessageDispatcher(const RefPtr<JsMessageDispatcher>& dispatcher) const;
215     void TransferComponentResponseData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data);
216     void TransferJsResponseData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const;
217 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
218     void TransferJsResponseDataPreview(int32_t callbackId, int32_t code, ResponseData responseData) const;
219 #endif
220     void TransferJsPluginGetError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const;
221     void TransferJsEventData(int32_t callbackId, int32_t code, std::vector<uint8_t>&& data) const;
222     void LoadPluginJsCode(std::string&& jsCode) const;
223     void LoadPluginJsByteCode(std::vector<uint8_t>&& jsCode, std::vector<int32_t>&& jsCodeLen) const;
224     void OnJsCallback(const std::string& callbackId, const std::string& data);
225     bool OnPageBackPress();
226     void OnBackGround();
227     void OnForground();
228     void OnConfigurationUpdated(const std::string& configurationData);
229     void OnActive();
230     void OnInactive();
231     bool OnStartContinuation();
232     void OnCompleteContinuation(int32_t code);
233     void OnRemoteTerminated();
234     void OnSaveData(std::string& data);
235     bool OnRestoreData(const std::string& data);
236     void OnNewRequest(const std::string& data);
237     void OnMemoryLevel(const int32_t level);
238     void OnNewWant(const std::string& data);
239     void CallPopPage();
240     void OnApplicationDestroy(const std::string& packageName);
241     void OnApplicationUpdateState(const std::string& packageName, Frontend::State state);
242     void SetColorMode(ColorMode colorMode);
243 
244     // Accessibility delegate functions.
GetJsAccessibilityManager()245     RefPtr<Framework::AccessibilityNodeManager> GetJsAccessibilityManager() const
246     {
247         return jsAccessibilityManager_;
248     }
249     void FireAccessibilityEvent(const AccessibilityEvent& accessibilityEvent);
250     void InitializeAccessibilityCallback();
251 
252     void OnMediaQueryUpdate() override;
253     void OnSurfaceChanged();
254     // JsEventHandler delegate functions.
255     void FireAsyncEvent(const std::string& eventId, const std::string& param, const std::string& jsonArgs);
256     bool FireSyncEvent(const std::string& eventId, const std::string& param, const std::string& jsonArgs);
257     void FireSyncEvent(
258         const std::string& eventId, const std::string& param, const std::string& jsonArgs, std::string& result);
259     void FireExternalEvent(const std::string& eventId, const std::string& componentId, const uint32_t nodeId);
260 
261     // FrontendDelegate overrides.
262     void Push(const std::string& uri, const std::string& params) override;
263     void Replace(const std::string& uri, const std::string& params) override;
264     void Back(const std::string& uri, const std::string& params = "") override;
265     void PostponePageTransition() override;
266     void LaunchPageTransition() override;
267     void Clear() override;
268     int32_t GetStackSize() const override;
269     void GetState(int32_t& index, std::string& name, std::string& path) override;
270     std::string GetParams() override;
271     void TriggerPageUpdate(int32_t pageId, bool directExecute = false) override;
272 
273     void PostJsTask(std::function<void()>&& task) override;
274 
275     const std::string& GetAppID() const override;
276     const std::string& GetAppName() const override;
277     const std::string& GetVersionName() const override;
278     int32_t GetVersionCode() const override;
279     WindowConfig& GetWindowConfig();
280     int32_t GetMinPlatformVersion() override;
281     bool IsUseLiteStyle();
282     bool IsWebFeature();
283 
284     void ShowToast(const std::string& message, int32_t duration, const std::string& bottom) override;
285     void ShowDialog(const std::string& title, const std::string& message, const std::vector<ButtonInfo>& buttons,
286         bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
287         const std::set<std::string>& callbacks) override;
288 
289     void EnableAlertBeforeBackPage(const std::string& message, std::function<void(int32_t)>&& callback) override;
290 
291     void DisableAlertBeforeBackPage() override;
292 
293     void ShowActionMenu(const std::string& title, const std::vector<ButtonInfo>& button,
294         std::function<void(int32_t, int32_t)>&& callback) override;
295 
296     Rect GetBoundingRectData(NodeId nodeId) override;
297 
298     std::string GetInspector(NodeId nodeId) override;
299 
300     void PushJsCallbackToRenderNode(NodeId id, double ratio, std::function<void(bool, double)>&& callback) override;
301     void RemoveVisibleChangeNode(NodeId id) override;
302 
303     // For async event.
304     void SetCallBackResult(const std::string& callBackId, const std::string& result) override;
305 
306     void WaitTimer(const std::string& callbackId, const std::string& delay, bool isInterval, bool isFirst) override;
307     void ClearTimer(const std::string& callbackId) override;
308 
309     void PostSyncTaskToPage(std::function<void()>&& task) override;
310     void AddTaskObserver(std::function<void()>&& task) override;
311     void RemoveTaskObserver() override;
312 
313     bool GetAssetContent(const std::string& url, std::string& content) override;
314     bool GetAssetContent(const std::string& url, std::vector<uint8_t>& content) override;
315     std::string GetAssetPath(const std::string& url) override;
316 
317     // i18n
318     void GetI18nData(std::unique_ptr<JsonValue>& json) override;
319 
320     void GetResourceConfiguration(std::unique_ptr<JsonValue>& json) override;
321 
322     void GetConfigurationCommon(const std::string& filePath, std::unique_ptr<JsonValue>& data) override;
323 
324     void ChangeLocale(const std::string& language, const std::string& countryOrRegion) override;
325 
326     void RegisterFont(const std::string& familyName, const std::string& familySrc) override;
327 
328     void HandleImage(const std::string& src, std::function<void(bool, int32_t, int32_t)>&& callback) override;
329 
330     void RequestAnimationFrame(const std::string& callbackId) override;
331 
332     void CancelAnimationFrame(const std::string& callbackId) override;
333 
334     SingleTaskExecutor GetAnimationJsTask() override;
335 
336     SingleTaskExecutor GetUiTask() override;
337 
338     void LoadResourceConfiguration(std::map<std::string, std::string>& sortedResourcePath,
339         std::unique_ptr<JsonValue>& currentResourceData) override;
340 
GetMediaQueryInfoInstance()341     const RefPtr<MediaQueryInfo>& GetMediaQueryInfoInstance() override
342     {
343         return mediaQueryInfo_;
344     }
345 
GetGroupJsBridge()346     const RefPtr<GroupJsBridge>& GetGroupJsBridge() override
347     {
348         return groupJsBridge_;
349     }
350 
351     RefPtr<PipelineContext> GetPipelineContext() override;
352 
SetGroupJsBridge(const RefPtr<GroupJsBridge> & groupJsBridge)353     void SetGroupJsBridge(const RefPtr<GroupJsBridge>& groupJsBridge)
354     {
355         groupJsBridge_ = groupJsBridge;
356     }
357 
358     RefPtr<JsAcePage> GetPage(int32_t pageId) const override;
359 
360 
GetCurrentReadyPage()361     WeakPtr<JsAcePage> GetCurrentReadyPage() const
362     {
363         return currentReadyPage_;
364     }
365 
GetPagePathInvalidFlag()366     bool GetPagePathInvalidFlag() const
367     {
368         return isPagePathInvalid_;
369     }
370 
371     void RebuildAllPages();
372 
373     void CallNativeHandler(const std::string& event, const std::string& params) override;
374 
375 private:
376     int32_t GenerateNextPageId();
377     void RecyclePageId(int32_t pageId);
378 
379     void LoadPage(int32_t pageId, const std::string& url, bool isMainPage, const std::string& params);
380     void OnPageReady(const RefPtr<Framework::JsAcePage>& page, const std::string& url, bool isMainPage);
381     void FlushPageCommand(const RefPtr<Framework::JsAcePage>& page, const std::string& url, bool isMainPage);
382     void AddPageLocked(const RefPtr<JsAcePage>& page);
383     void SetCurrentPage(int32_t pageId);
SetCurrentReadyPage(const WeakPtr<JsAcePage> & page)384     void SetCurrentReadyPage(const WeakPtr<JsAcePage>& page)
385     {
386         currentReadyPage_ = page;
387     }
388 
389     void OnPushPageSuccess(const RefPtr<JsAcePage>& page, const std::string& url);
390     void OnPopToPageSuccess(const std::string& url);
391     void PopToPage(const std::string& url);
392     int32_t OnPopPageSuccess();
393     void PopPage();
394 
395     void PopPageTransitionListener(const TransitionEvent& event, int32_t destroyPageId);
396 
397     void PopToPageTransitionListener(const TransitionEvent& event, const std::string& url, int32_t pageId);
398 
399     int32_t OnClearInvisiblePagesSuccess();
400     void ClearInvisiblePages();
401 
402     void OnReplacePageSuccess(const RefPtr<JsAcePage>& page, const std::string& url);
403     void ReplacePage(const RefPtr<JsAcePage>& page, const std::string& url);
404     void LoadReplacePage(int32_t pageId, const std::string& url, const std::string& params);
405 
406     uint64_t GetSystemRealTime();
407 
408     // Page lifecycle
409     void OnPageShow();
410     void OnPageHide();
411     void OnPageDestroy(int32_t pageId);
412 
413     int32_t GetRunningPageId() const;
414     std::string GetRunningPageUrl() const;
415     int32_t GetPageIdByUrl(const std::string& url);
416 
417     void ResetStagingPage();
418     void FlushAnimationTasks();
419     void ParseManifest();
420 
421     void BackImplement(const std::string& uri);
422 
423     void ClearAlertCallback(PageInfo pageInfo);
424 
425     std::atomic<uint64_t> pageIdPool_ = 0;
426     int32_t callbackCnt_ = 0;
427     int32_t pageId_ = -1;
428     bool isRouteStackFull_ = false;
429     bool isStagingPageExist_ = false;
430     std::string mainPagePath_;
431     std::string backUri_;
432     std::vector<PageInfo> pageRouteStack_;
433     std::unordered_map<int32_t, RefPtr<JsAcePage>> pageMap_;
434     std::unordered_map<int32_t, std::string> pageParamMap_;
435     std::unordered_map<int32_t, std::string> jsCallBackResult_;
436     WeakPtr<JsAcePage> currentReadyPage_;
437 
438     LoadJsCallback loadJs_;
439     JsMessageDispatcherSetterCallback dispatcherCallback_;
440     EventCallback asyncEvent_;
441     EventCallback syncEvent_;
442     ExternalEventCallback externalEvent_;
443     UpdatePageCallback updatePage_;
444     ResetStagingPageCallback resetStagingPage_;
445     DestroyPageCallback destroyPage_;
446     DestroyApplicationCallback destroyApplication_;
447     UpdateApplicationStateCallback updateApplicationState_;
448     OnStartContinuationCallBack onStartContinuationCallBack_;
449     OnCompleteContinuationCallBack onCompleteContinuationCallBack_;
450     OnRemoteTerminatedCallBack onRemoteTerminatedCallBack_;
451     OnSaveDataCallBack onSaveDataCallBack_;
452     OnRestoreDataCallBack onRestoreDataCallBack_;
453     TimerCallback timer_;
454     std::unordered_map<std::string, CancelableCallback<void()>> timeoutTaskMap_;
455     MediaQueryCallback mediaQueryCallback_;
456     RequestAnimationCallback requestAnimationCallback_;
457     JsCallback jsCallback_;
458     RefPtr<Framework::ManifestParser> manifestParser_;
459     RefPtr<Framework::AccessibilityNodeManager> jsAccessibilityManager_;
460     RefPtr<MediaQueryInfo> mediaQueryInfo_;
461     RefPtr<GroupJsBridge> groupJsBridge_;
462 
463     RefPtr<TaskExecutor> taskExecutor_;
464     CallNativeHandlerCallback callNativeHandler_;
465 
466     PipelineContextHolder pipelineContextHolder_;
467 
468     BaseId::IdType pageTransitionListenerId_ = 0L;
469     std::queue<std::string> animationFrameTaskIds_;
470     std::unordered_map<std::string, CancelableCallback<void()>> animationFrameTaskMap_;
471 
472     mutable std::mutex mutex_;
473     mutable std::once_flag onceFlag_;
474 
475     bool isPagePathInvalid_ = false;
476 };
477 
478 } // namespace OHOS::Ace::Framework
479 
480 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_FRONTEND_DELEGATE_IMPL_H
481