/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_FRONTEND_DELEGATE_IMPL_H #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_FRONTEND_DELEGATE_IMPL_H #include #include #include #include "base/memory/ace_type.h" #include "base/thread/cancelable_callback.h" #include "base/utils/measure_util.h" #include "core/common/frontend.h" #include "core/common/js_message_dispatcher.h" #include "core/components/dialog/dialog_component.h" #include "core/pipeline/pipeline_base.h" #include "frameworks/bridge/common/accessibility/accessibility_node_manager.h" #include "frameworks/bridge/common/manifest/manifest_parser.h" #include "frameworks/bridge/common/utils/pipeline_context_holder.h" #include "frameworks/bridge/js_frontend/engine/common/group_js_bridge.h" #include "frameworks/bridge/js_frontend/frontend_delegate.h" #include "frameworks/bridge/js_frontend/js_ace_page.h" namespace OHOS::Ace::Framework { using LoadJsCallback = std::function&, bool isMainPage)>; using JsMessageDispatcherSetterCallback = std::function&)>; using EventCallback = std::function; using ExternalEventCallback = std::function; using UpdatePageCallback = std::function&)>; using ResetStagingPageCallback = std::function; using MediaQueryCallback = std::function; using LayoutInspectorCallback = std::function; using DrawInspectorCallback = std::function; using DestroyPageCallback = std::function; using DestroyApplicationCallback = std::function; using UpdateApplicationStateCallback = std::function; using TimerCallback = std::function; using RequestAnimationCallback = std::function; using JsCallback = std::function; using OnWindowDisplayModeChangedCallBack = std::function; using OnConfigurationUpdatedCallBack = std::function; using OnNewWantCallBack = std::function; using OnSaveAbilityStateCallBack = std::function; using OnRestoreAbilityStateCallBack = std::function; using OnActiveCallBack = std::function; using OnInactiveCallBack = std::function; using OnMemoryLevelCallBack = std::function; using OnStartContinuationCallBack = std::function; using OnCompleteContinuationCallBack = std::function; using OnRemoteTerminatedCallBack = std::function; using OnSaveDataCallBack = std::function; using OnRestoreDataCallBack = std::function; using CallNativeHandlerCallback = std::function; struct PageInfo { int32_t pageId = -1; std::string url; bool isRestore = false; std::function alertCallback; DialogProperties dialogProperties; }; struct FrontendDelegateImplBuilder { RefPtr taskExecutor; LoadJsCallback loadCallback; JsMessageDispatcherSetterCallback transferCallback; EventCallback asyncEventCallback; EventCallback syncEventCallback; ExternalEventCallback externalEventCallback; UpdatePageCallback updatePageCallback; ResetStagingPageCallback resetStagingPageCallback; DestroyPageCallback destroyPageCallback; DestroyApplicationCallback destroyApplicationCallback; UpdateApplicationStateCallback updateApplicationStateCallback; OnStartContinuationCallBack onStartContinuationCallBack; OnCompleteContinuationCallBack onCompleteContinuationCallBack; OnRemoteTerminatedCallBack onRemoteTerminatedCallBack; OnSaveDataCallBack onSaveDataCallBack; OnRestoreDataCallBack onRestoreDataCallBack; TimerCallback timerCallback; MediaQueryCallback mediaQueryCallback; RequestAnimationCallback requestAnimationCallback; JsCallback jsCallback; OnWindowDisplayModeChangedCallBack onWindowDisplayModeChangedCallBack; OnNewWantCallBack onNewWantCallBack; OnSaveAbilityStateCallBack onSaveAbilityStateCallBack; OnRestoreAbilityStateCallBack onRestoreAbilityStateCallBack; OnActiveCallBack onActiveCallBack; OnInactiveCallBack onInactiveCallBack; OnMemoryLevelCallBack onMemoryLevelCallBack; CallNativeHandlerCallback callNativeHandler; void* ability; }; class DelegateClient { public: using RouterPushCallback = std::function; using GetWebPageUrlCallback = std::function; using IsPagePathInvalidCallback = std::function; DelegateClient &operator = (const DelegateClient &) = delete; DelegateClient(const DelegateClient &) = delete; ~DelegateClient() = default; static DelegateClient& GetInstance() { static DelegateClient instance; return instance; } void RegisterRouterPushCallback(RouterPushCallback &&callback) { routerPushCallback_ = callback; } void RouterPush(const std::string& url) { if (routerPushCallback_) { return routerPushCallback_(url); } } void RegisterGetWebPageUrlCallback(GetWebPageUrlCallback &&callback) { getWebPageUrlCallback_ = callback; } void GetWebPageUrl(std::string& pageUrl, int32_t& pageId) { if (getWebPageUrlCallback_) { return getWebPageUrlCallback_(pageUrl, pageId); } } void RegisterIsPagePathInvalidCallback(IsPagePathInvalidCallback &&callback) { isPagePathInvalidCallback_ = callback; } void GetIsPagePathInvalid(bool& isPageInvalid) { if (isPagePathInvalidCallback_) { return isPagePathInvalidCallback_(isPageInvalid); } } private: DelegateClient() = default; RouterPushCallback routerPushCallback_; GetWebPageUrlCallback getWebPageUrlCallback_; IsPagePathInvalidCallback isPagePathInvalidCallback_; }; class FrontendDelegateImpl : public FrontendDelegate { DECLARE_ACE_TYPE(FrontendDelegateImpl, FrontendDelegate); public: explicit FrontendDelegateImpl(const FrontendDelegateImplBuilder& builder); ~FrontendDelegateImpl() override; void AttachPipelineContext(const RefPtr& context) override; // JsFrontend delegate functions. UIContentErrorCode RunPage(const std::string& url, const std::string& params); void SetJsMessageDispatcher(const RefPtr& dispatcher) const; void TransferComponentResponseData(int32_t callbackId, int32_t code, std::vector&& data); void TransferJsResponseData(int32_t callbackId, int32_t code, std::vector&& data) const; #if defined(PREVIEW) void TransferJsResponseDataPreview(int32_t callbackId, int32_t code, ResponseData responseData) const; #endif void TransferJsPluginGetError(int32_t callbackId, int32_t errorCode, std::string&& errorMessage) const; void TransferJsEventData(int32_t callbackId, int32_t code, std::vector&& data) const; void LoadPluginJsCode(std::string&& jsCode) const; void LoadPluginJsByteCode(std::vector&& jsCode, std::vector&& jsCodeLen) const; void OnJsCallback(const std::string& callbackId, const std::string& data); bool OnPageBackPress(); void OnBackGround(); void OnForeground(); void OnConfigurationUpdated(const std::string& configurationData); void OnActive(); void OnInactive(); bool OnStartContinuation(); void OnCompleteContinuation(int32_t code); void OnRemoteTerminated(); void OnSaveData(std::string& data); bool OnRestoreData(const std::string& data); void OnNewRequest(const std::string& data); void OnMemoryLevel(const int32_t level); void OnNewWant(const std::string& data); void CallPopPage(); void OnApplicationDestroy(const std::string& packageName); void OnApplicationUpdateState(const std::string& packageName, Frontend::State state); void SetColorMode(ColorMode colorMode); // Accessibility delegate functions. RefPtr GetJsAccessibilityManager() const { return jsAccessibilityManager_; } void FireAccessibilityEvent(const AccessibilityEvent& accessibilityEvent); void InitializeAccessibilityCallback(); void OnMediaQueryUpdate(bool isSynchronous = false) override; void OnSurfaceChanged(); void OnLayoutCompleted(const std::string& componentId); void OnDrawCompleted(const std::string& componentId); // JsEventHandler delegate functions. void FireAsyncEvent(const std::string& eventId, const std::string& param, const std::string& jsonArgs); bool FireSyncEvent(const std::string& eventId, const std::string& param, const std::string& jsonArgs); void FireSyncEvent( const std::string& eventId, const std::string& param, const std::string& jsonArgs, std::string& result); void FireExternalEvent( const std::string& eventId, const std::string& componentId, const uint32_t nodeId, const bool isDestroy); // FrontendDelegate overrides. void Push(const std::string& uri, const std::string& params) override; void PushWithCallback(const std::string& uri, const std::string& params, bool recoverable, const std::function& errorCallback, uint32_t routerMode = 0) override; void Replace(const std::string& uri, const std::string& params) override; void ReplaceWithCallback(const std::string& uri, const std::string& params, bool recoverable, const std::function& errorCallback, uint32_t routerMode = 0) override; void Back(const std::string& uri, const std::string& params) override; void PostponePageTransition() override; void LaunchPageTransition() override; void Clear() override; int32_t GetStackSize() const override; void GetState(int32_t& index, std::string& name, std::string& path) override; size_t GetComponentsCount() override; std::string GetParams() override; void TriggerPageUpdate(int32_t pageId, bool directExecute = false) override; void PostJsTask(std::function&& task, const std::string& name) override; void PostUITask(std::function&& task, const std::string& name) override; const std::string& GetAppID() const override; const std::string& GetAppName() const override; const std::string& GetVersionName() const override; int32_t GetVersionCode() const override; WindowConfig& GetWindowConfig(); int32_t GetMinPlatformVersion() override; bool IsUseLiteStyle(); bool IsWebFeature(); double MeasureText(MeasureContext context) override; Size MeasureTextSize(MeasureContext context) override; void ShowToast(const NG::ToastInfo& toastInfo, std::function&& callback) override; void ShowDialog(const std::string& title, const std::string& message, const std::vector& buttons, bool autoCancel, std::function&& callback, const std::set& callbacks) override; void EnableAlertBeforeBackPage(const std::string& message, std::function&& callback) override; void DisableAlertBeforeBackPage() override; void ShowActionMenu(const std::string& title, const std::vector& button, std::function&& callback) override; Rect GetBoundingRectData(NodeId nodeId) override; std::string GetInspector(NodeId nodeId) override; void PushJsCallbackToRenderNode(NodeId id, double ratio, std::function&& callback) override; // For async event. void SetCallBackResult(const std::string& callBackId, const std::string& result) override; void WaitTimer(const std::string& callbackId, const std::string& delay, bool isInterval, bool isFirst) override; void ClearTimer(const std::string& callbackId) override; void PostSyncTaskToPage(std::function&& task, const std::string& name) override; void AddTaskObserver(std::function&& task) override; void RemoveTaskObserver() override; bool GetAssetContent(const std::string& url, std::string& content) override; bool GetAssetContent(const std::string& url, std::vector& content) override; std::string GetAssetPath(const std::string& url) override; // i18n void GetI18nData(std::unique_ptr& json) override; void GetResourceConfiguration(std::unique_ptr& json) override; void GetConfigurationCommon(const std::string& filePath, std::unique_ptr& data) override; void ChangeLocale(const std::string& language, const std::string& countryOrRegion) override; void RegisterFont(const std::string& familyName, const std::string& familySrc, const std::string& bundleName = "", const std::string& moduleName = "") override; void GetSystemFontList(std::vector& fontList) override; bool GetSystemFont(const std::string& fontName, FontInfo& fontInfo) override; void GetUIFontConfig(FontConfigJsonInfo& fontConfigJsonInfo) override; void HandleImage(const std::string& src, std::function&& callback) override; void RequestAnimationFrame(const std::string& callbackId) override; void CancelAnimationFrame(const std::string& callbackId) override; SingleTaskExecutor GetAnimationJsTask() override; SingleTaskExecutor GetUiTask() override; void LoadResourceConfiguration(std::map& sortedResourcePath, std::unique_ptr& currentResourceData) override; const RefPtr& GetMediaQueryInfoInstance() override { return mediaQueryInfo_; } const RefPtr& GetGroupJsBridge() override { return groupJsBridge_; } RefPtr GetPipelineContext() override; void SetGroupJsBridge(const RefPtr& groupJsBridge) { groupJsBridge_ = groupJsBridge; } RefPtr GetPage(int32_t pageId) const override; WeakPtr GetCurrentReadyPage() const { return currentReadyPage_; } bool GetPagePathInvalidFlag() const { return isPagePathInvalid_; } void RebuildAllPages(); void CallNativeHandler(const std::string& event, const std::string& params) override; private: void Push(const std::string& uri, const std::string& params, const std::function& errorCallback); void Replace(const std::string& uri, const std::string& params, const std::function& errorCallback); int32_t GenerateNextPageId(); void RecyclePageId(int32_t pageId); UIContentErrorCode LoadPage(int32_t pageId, const std::string& url, bool isMainPage, const std::string& params); void OnPageReady(const RefPtr& page, const std::string& url, bool isMainPage); void FlushPageCommand(const RefPtr& page, const std::string& url, bool isMainPage); void AddPageLocked(const RefPtr& page); void SetCurrentPage(int32_t pageId); void SetCurrentReadyPage(const WeakPtr& page) { currentReadyPage_ = page; } void OnPushPageSuccess(const RefPtr& page, const std::string& url); void OnPopToPageSuccess(const std::string& url); void PopToPage(const std::string& url); int32_t OnPopPageSuccess(); void PopPage(); void PushPageTransitionListener(const TransitionEvent& event, const RefPtr& page); void PopPageTransitionListener(const TransitionEvent& event, int32_t destroyPageId); void PopToPageTransitionListener(const TransitionEvent& event, const std::string& url, int32_t pageId); int32_t OnClearInvisiblePagesSuccess(); void ClearInvisiblePages(); void OnReplacePageSuccess(const RefPtr& page, const std::string& url); void ReplacePage(const RefPtr& page, const std::string& url); void LoadReplacePage(int32_t pageId, const std::string& url, const std::string& params); uint64_t GetSystemRealTime(); // Page lifecycle void OnPageShow(); void OnPageHide(); void OnPageDestroy(int32_t pageId); int32_t GetRunningPageId() const; std::string GetRunningPageUrl() const; int32_t GetPageIdByUrl(const std::string& url); void ResetStagingPage(); void FlushAnimationTasks(); void ParseManifest(); void BackImplement(const std::string& uri, const std::string& params); void ClearAlertCallback(PageInfo pageInfo); void GetAssetFromI18n(const std::string& fileFullPath, std::unique_ptr& data); std::atomic pageIdPool_ = 0; int32_t callbackCnt_ = 0; int32_t pageId_ = -1; bool isRouteStackFull_ = false; bool isStagingPageExist_ = false; std::string mainPagePath_; std::string backUri_; std::string backParam_; std::vector pageRouteStack_; std::unordered_map> pageMap_; std::unordered_map pageParamMap_; std::unordered_map jsCallBackResult_; WeakPtr currentReadyPage_; LoadJsCallback loadJs_; JsMessageDispatcherSetterCallback dispatcherCallback_; EventCallback asyncEvent_; EventCallback syncEvent_; ExternalEventCallback externalEvent_; UpdatePageCallback updatePage_; ResetStagingPageCallback resetStagingPage_; DestroyPageCallback destroyPage_; DestroyApplicationCallback destroyApplication_; UpdateApplicationStateCallback updateApplicationState_; OnStartContinuationCallBack onStartContinuationCallBack_; OnCompleteContinuationCallBack onCompleteContinuationCallBack_; OnRemoteTerminatedCallBack onRemoteTerminatedCallBack_; OnSaveDataCallBack onSaveDataCallBack_; OnRestoreDataCallBack onRestoreDataCallBack_; TimerCallback timer_; std::unordered_map> timeoutTaskMap_; MediaQueryCallback mediaQueryCallback_; RequestAnimationCallback requestAnimationCallback_; JsCallback jsCallback_; RefPtr manifestParser_; RefPtr jsAccessibilityManager_; RefPtr mediaQueryInfo_; RefPtr groupJsBridge_; RefPtr taskExecutor_; CallNativeHandlerCallback callNativeHandler_; PipelineContextHolder pipelineContextHolder_; BaseId::IdType pageTransitionListenerId_ = 0L; std::queue animationFrameTaskIds_; std::unordered_map> animationFrameTaskMap_; mutable std::mutex mutex_; mutable std::once_flag onceFlag_; bool isPagePathInvalid_ = false; }; } // namespace OHOS::Ace::Framework #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_JS_FRONTEND_FRONTEND_DELEGATE_IMPL_H