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