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