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