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