1 /*
2 * Copyright (c) 2022-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 #include "frameworks/bridge/declarative_frontend/ng/frontend_delegate_declarative_ng.h"
17
18 #include "base/i18n/localization.h"
19 #include "base/log/ace_trace.h"
20 #include "base/log/event_report.h"
21 #include "base/resource/ace_res_config.h"
22 #include "base/thread/background_task_executor.h"
23 #include "base/utils/measure_util.h"
24 #include "base/utils/utils.h"
25 #include "core/common/ace_application_info.h"
26 #include "core/common/container.h"
27 #include "core/common/thread_checker.h"
28 #include "core/components_ng/base/view_stack_model.h"
29 #include "core/components_ng/pattern/overlay/overlay_manager.h"
30 #include "core/components_ng/pattern/stage/page_pattern.h"
31 #include "core/components_ng/render/adapter/component_snapshot.h"
32 #include "core/pipeline_ng/pipeline_context.h"
33 #include "frameworks/bridge/common/utils/utils.h"
34
35 namespace OHOS::Ace::Framework {
36
37 namespace {
38
39 const char MANIFEST_JSON[] = "manifest.json";
40 const char PAGES_JSON[] = "main_pages.json";
41 constexpr int32_t TOAST_TIME_MAX = 10000; // ms
42 constexpr int32_t TOAST_TIME_DEFAULT = 1500; // ms
43 constexpr int32_t CALLBACK_ERRORCODE_CANCEL = 1;
44 constexpr int32_t CALLBACK_DATACODE_ZERO = 0;
45
46 // helper function to run OverlayManager task
47 // ensures that the task runs in subwindow instead of main Window
MainWindowOverlay(std::function<void (RefPtr<NG::OverlayManager>)> && task)48 void MainWindowOverlay(std::function<void(RefPtr<NG::OverlayManager>)>&& task)
49 {
50 auto currentId = Container::CurrentId();
51 ContainerScope scope(currentId);
52 auto context = NG::PipelineContext::GetCurrentContext();
53 CHECK_NULL_VOID(context);
54 auto overlayManager = context->GetOverlayManager();
55 context->GetTaskExecutor()->PostTask(
56 [task = std::move(task), weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
57 auto overlayManager = weak.Upgrade();
58 task(overlayManager);
59 },
60 TaskExecutor::TaskType::UI);
61 }
62 } // namespace
63
FrontendDelegateDeclarativeNG(const RefPtr<TaskExecutor> & taskExecutor)64 FrontendDelegateDeclarativeNG::FrontendDelegateDeclarativeNG(const RefPtr<TaskExecutor>& taskExecutor)
65 : taskExecutor_(taskExecutor), manifestParser_(AceType::MakeRefPtr<Framework::ManifestParser>()),
66 mediaQueryInfo_(AceType::MakeRefPtr<MediaQueryInfo>()),
67 jsAccessibilityManager_(AccessibilityNodeManager::Create())
68 {
69 LOGD("FrontendDelegateDeclarativeNG create");
70 }
71
SetMediaQueryCallback(MediaQueryCallback && mediaQueryCallback)72 void FrontendDelegateDeclarativeNG::SetMediaQueryCallback(MediaQueryCallback&& mediaQueryCallback)
73 {
74 mediaQueryCallback_ = mediaQueryCallback;
75 }
76
SetLayoutInspectorCallback(const LayoutInspectorCallback & layoutInspectorCallback)77 void FrontendDelegateDeclarativeNG::SetLayoutInspectorCallback(const LayoutInspectorCallback& layoutInspectorCallback)
78 {
79 layoutInspectorCallback_ = layoutInspectorCallback;
80 }
81
SetDrawInspectorCallback(const DrawInspectorCallback & drawInspectorCallback)82 void FrontendDelegateDeclarativeNG::SetDrawInspectorCallback(const DrawInspectorCallback& drawInspectorCallback)
83 {
84 drawInspectorCallback_ = drawInspectorCallback;
85 }
86
SetOnStartContinuationCallBack(OnStartContinuationCallBack && onStartContinuationCallBack)87 void FrontendDelegateDeclarativeNG::SetOnStartContinuationCallBack(
88 OnStartContinuationCallBack&& onStartContinuationCallBack)
89 {
90 onStartContinuationCallBack_ = onStartContinuationCallBack;
91 }
92
SetOnCompleteContinuationCallBack(OnCompleteContinuationCallBack && onCompleteContinuationCallBack)93 void FrontendDelegateDeclarativeNG::SetOnCompleteContinuationCallBack(
94 OnCompleteContinuationCallBack&& onCompleteContinuationCallBack)
95 {
96 onCompleteContinuationCallBack_ = onCompleteContinuationCallBack;
97 }
98
SetOnSaveDataCallBack(OnSaveDataCallBack && onSaveDataCallBack)99 void FrontendDelegateDeclarativeNG::SetOnSaveDataCallBack(OnSaveDataCallBack&& onSaveDataCallBack)
100 {
101 onSaveDataCallBack_ = onSaveDataCallBack;
102 }
103
SetOnRemoteTerminatedCallBack(OnRemoteTerminatedCallBack && onRemoteTerminatedCallBack)104 void FrontendDelegateDeclarativeNG::SetOnRemoteTerminatedCallBack(
105 OnRemoteTerminatedCallBack&& onRemoteTerminatedCallBack)
106 {
107 onRemoteTerminatedCallBack_ = onRemoteTerminatedCallBack;
108 }
109
SetOnRestoreDataCallBack(OnRestoreDataCallBack && onRestoreDataCallBack)110 void FrontendDelegateDeclarativeNG::SetOnRestoreDataCallBack(OnRestoreDataCallBack&& onRestoreDataCallBack)
111 {
112 onRestoreDataCallBack_ = onRestoreDataCallBack;
113 }
114
SetDestroyApplicationCallback(DestroyApplicationCallback && destroyApplicationCallback)115 void FrontendDelegateDeclarativeNG::SetDestroyApplicationCallback(
116 DestroyApplicationCallback&& destroyApplicationCallback)
117 {
118 destroyApplication_ = destroyApplicationCallback;
119 }
120
SetUpdateApplicationStateCallback(UpdateApplicationStateCallback && updateApplicationStateCallback)121 void FrontendDelegateDeclarativeNG::SetUpdateApplicationStateCallback(
122 UpdateApplicationStateCallback&& updateApplicationStateCallback)
123 {
124 updateApplicationState_ = updateApplicationStateCallback;
125 }
126
SetOnWindowDisplayModeChangedCallback(OnWindowDisplayModeChangedCallBack && onWindowDisplayModeChangedCallBack)127 void FrontendDelegateDeclarativeNG::SetOnWindowDisplayModeChangedCallback(
128 OnWindowDisplayModeChangedCallBack&& onWindowDisplayModeChangedCallBack)
129 {
130 onWindowDisplayModeChanged_ = onWindowDisplayModeChangedCallBack;
131 }
132
SetExternalEventCallback(ExternalEventCallback && externalEventCallback)133 void FrontendDelegateDeclarativeNG::SetExternalEventCallback(ExternalEventCallback&& externalEventCallback)
134 {
135 externalEvent_ = externalEventCallback;
136 }
137
SetTimerCallback(TimerCallback && timerCallback)138 void FrontendDelegateDeclarativeNG::SetTimerCallback(TimerCallback&& timerCallback)
139 {
140 timer_ = timerCallback;
141 }
142
AttachPipelineContext(const RefPtr<PipelineBase> & context)143 void FrontendDelegateDeclarativeNG::AttachPipelineContext(const RefPtr<PipelineBase>& context)
144 {
145 if (!context) {
146 return;
147 }
148 context->SetOnPageShow([weak = AceType::WeakClaim(this)] {
149 auto delegate = weak.Upgrade();
150 if (delegate) {
151 delegate->OnPageShow();
152 }
153 });
154
155 pipelineContextHolder_.Attach(context);
156 jsAccessibilityManager_->SetPipelineContext(context);
157 jsAccessibilityManager_->InitializeCallback();
158 }
159
AttachSubPipelineContext(const RefPtr<PipelineBase> & context)160 void FrontendDelegateDeclarativeNG::AttachSubPipelineContext(const RefPtr<PipelineBase>& context)
161 {
162 if (!context) {
163 return;
164 }
165 jsAccessibilityManager_->AddSubPipelineContext(context);
166 }
167
RunPage(const std::string & url,const std::string & params,const std::string & profile)168 void FrontendDelegateDeclarativeNG::RunPage(
169 const std::string& url, const std::string& params, const std::string& profile)
170 {
171 ACE_SCOPED_TRACE("FrontendDelegateDeclarativeNG::RunPage");
172
173 LOGI("FrontendDelegateDeclarativeNG RunPage url=%{public}s", url.c_str());
174 std::string jsonContent;
175 if (GetAssetContent(MANIFEST_JSON, jsonContent)) {
176 manifestParser_->Parse(jsonContent);
177 manifestParser_->Printer();
178 } else if (!profile.empty() && GetAssetContent(profile, jsonContent)) {
179 LOGI("Parse profile %{public}s", profile.c_str());
180 manifestParser_->Parse(jsonContent);
181 } else if (GetAssetContent(PAGES_JSON, jsonContent)) {
182 LOGI("Parse main_pages.json");
183 manifestParser_->Parse(jsonContent);
184 } else {
185 LOGE("RunPage parse manifest.json failed");
186 }
187 std::string mainPagePath;
188 if (!url.empty()) {
189 mainPagePath = manifestParser_->GetRouter()->GetPagePath(url);
190 } else {
191 mainPagePath = manifestParser_->GetRouter()->GetEntry();
192 }
193 taskExecutor_->PostTask(
194 [manifestParser = manifestParser_, delegate = Claim(this),
195 weakPtr = WeakPtr<NG::PageRouterManager>(pageRouterManager_), url, params]() {
196 auto pageRouterManager = weakPtr.Upgrade();
197 CHECK_NULL_VOID(pageRouterManager);
198 pageRouterManager->SetManifestParser(manifestParser);
199 pageRouterManager->RunPage(url, params);
200 auto pipeline = delegate->GetPipelineContext();
201 // TODO: get platform version from context, and should stored in AceApplicationInfo.
202 if (manifestParser->GetMinPlatformVersion() > 0) {
203 pipeline->SetMinPlatformVersion(manifestParser->GetMinPlatformVersion());
204 }
205 },
206 TaskExecutor::TaskType::JS);
207 }
208
OnConfigurationUpdated(const std::string & data)209 void FrontendDelegateDeclarativeNG::OnConfigurationUpdated(const std::string& data)
210 {
211 // only support mediaQueryUpdate
212 OnMediaQueryUpdate();
213 }
214
OnStartContinuation()215 bool FrontendDelegateDeclarativeNG::OnStartContinuation()
216 {
217 bool ret = false;
218 taskExecutor_->PostSyncTask(
219 [weak = AceType::WeakClaim(this), &ret] {
220 auto delegate = weak.Upgrade();
221 if (delegate && delegate->onStartContinuationCallBack_) {
222 ret = delegate->onStartContinuationCallBack_();
223 }
224 },
225 TaskExecutor::TaskType::JS);
226 return ret;
227 }
228
OnCompleteContinuation(int32_t code)229 void FrontendDelegateDeclarativeNG::OnCompleteContinuation(int32_t code)
230 {
231 taskExecutor_->PostSyncTask(
232 [weak = AceType::WeakClaim(this), code] {
233 auto delegate = weak.Upgrade();
234 if (delegate && delegate->onCompleteContinuationCallBack_) {
235 delegate->onCompleteContinuationCallBack_(code);
236 }
237 },
238 TaskExecutor::TaskType::JS);
239 }
240
OnRemoteTerminated()241 void FrontendDelegateDeclarativeNG::OnRemoteTerminated()
242 {
243 taskExecutor_->PostSyncTask(
244 [weak = AceType::WeakClaim(this)] {
245 auto delegate = weak.Upgrade();
246 if (delegate && delegate->onRemoteTerminatedCallBack_) {
247 delegate->onRemoteTerminatedCallBack_();
248 }
249 },
250 TaskExecutor::TaskType::JS);
251 }
252
OnSaveData(std::string & data)253 void FrontendDelegateDeclarativeNG::OnSaveData(std::string& data)
254 {
255 std::string savedData;
256 taskExecutor_->PostSyncTask(
257 [weak = AceType::WeakClaim(this), &savedData] {
258 auto delegate = weak.Upgrade();
259 if (delegate && delegate->onSaveDataCallBack_) {
260 delegate->onSaveDataCallBack_(savedData);
261 }
262 },
263 TaskExecutor::TaskType::JS);
264 std::string pageUri = GetCurrentPageUrl();
265 data = std::string("{\"url\":\"").append(pageUri).append("\",\"__remoteData\":").append(savedData).append("}");
266 }
267
OnRestoreData(const std::string & data)268 bool FrontendDelegateDeclarativeNG::OnRestoreData(const std::string& data)
269 {
270 bool ret = false;
271 taskExecutor_->PostSyncTask(
272 [weak = AceType::WeakClaim(this), &data, &ret] {
273 auto delegate = weak.Upgrade();
274 if (delegate && delegate->onRestoreDataCallBack_) {
275 ret = delegate->onRestoreDataCallBack_(data);
276 }
277 },
278 TaskExecutor::TaskType::JS);
279 return ret;
280 }
281
OnApplicationDestroy(const std::string & packageName)282 void FrontendDelegateDeclarativeNG::OnApplicationDestroy(const std::string& packageName)
283 {
284 taskExecutor_->PostSyncTask(
285 [destroyApplication = destroyApplication_, packageName] { destroyApplication(packageName); },
286 TaskExecutor::TaskType::JS);
287 }
288
UpdateApplicationState(const std::string & packageName,Frontend::State state)289 void FrontendDelegateDeclarativeNG::UpdateApplicationState(const std::string& packageName, Frontend::State state)
290 {
291 taskExecutor_->PostTask([updateApplicationState = updateApplicationState_, packageName,
292 state] { updateApplicationState(packageName, state); },
293 TaskExecutor::TaskType::JS);
294 }
295
OnWindowDisplayModeChanged(bool isShownInMultiWindow,const std::string & data)296 void FrontendDelegateDeclarativeNG::OnWindowDisplayModeChanged(bool isShownInMultiWindow, const std::string& data)
297 {
298 taskExecutor_->PostTask([onWindowDisplayModeChanged = onWindowDisplayModeChanged_, isShownInMultiWindow,
299 data] { onWindowDisplayModeChanged(isShownInMultiWindow, data); },
300 TaskExecutor::TaskType::JS);
301 }
302
NotifyAppStorage(const WeakPtr<Framework::JsEngine> & jsEngineWeak,const std::string & key,const std::string & value)303 void FrontendDelegateDeclarativeNG::NotifyAppStorage(
304 const WeakPtr<Framework::JsEngine>& jsEngineWeak, const std::string& key, const std::string& value)
305 {
306 taskExecutor_->PostTask(
307 [jsEngineWeak, key, value] {
308 auto jsEngine = jsEngineWeak.Upgrade();
309 if (!jsEngine) {
310 return;
311 }
312 jsEngine->NotifyAppStorage(key, value);
313 },
314 TaskExecutor::TaskType::JS);
315 }
316
FireAccessibilityEvent(const AccessibilityEvent & accessibilityEvent)317 void FrontendDelegateDeclarativeNG::FireAccessibilityEvent(const AccessibilityEvent& accessibilityEvent)
318 {
319 jsAccessibilityManager_->SendAccessibilityAsyncEvent(accessibilityEvent);
320 }
321
InitializeAccessibilityCallback()322 void FrontendDelegateDeclarativeNG::InitializeAccessibilityCallback()
323 {
324 jsAccessibilityManager_->InitializeCallback();
325 }
326
FireExternalEvent(const std::string &,const std::string & componentId,const uint32_t nodeId,const bool isDestroy)327 void FrontendDelegateDeclarativeNG::FireExternalEvent(
328 const std::string& /* eventId */, const std::string& componentId, const uint32_t nodeId, const bool isDestroy)
329 {
330 taskExecutor_->PostSyncTask(
331 [weak = AceType::WeakClaim(this), componentId, nodeId, isDestroy] {
332 auto delegate = weak.Upgrade();
333 if (delegate) {
334 delegate->externalEvent_(componentId, nodeId, isDestroy);
335 }
336 },
337 TaskExecutor::TaskType::JS);
338 }
339
WaitTimer(const std::string & callbackId,const std::string & delay,bool isInterval,bool isFirst)340 void FrontendDelegateDeclarativeNG::WaitTimer(
341 const std::string& callbackId, const std::string& delay, bool isInterval, bool isFirst)
342 {
343 if (!isFirst) {
344 auto timeoutTaskIter = timeoutTaskMap_.find(callbackId);
345 // If not find the callbackId in map, means this timer already was removed,
346 // no need create a new cancelableTimer again.
347 if (timeoutTaskIter == timeoutTaskMap_.end()) {
348 return;
349 }
350 }
351
352 int32_t delayTime = StringToInt(delay);
353 // CancelableCallback class can only be executed once.
354 CancelableCallback<void()> cancelableTimer;
355 cancelableTimer.Reset([callbackId, delay, isInterval, call = timer_] { call(callbackId, delay, isInterval); });
356 auto result = timeoutTaskMap_.try_emplace(callbackId, cancelableTimer);
357 if (!result.second) {
358 result.first->second = cancelableTimer;
359 }
360 taskExecutor_->PostDelayedTask(cancelableTimer, TaskExecutor::TaskType::JS, delayTime);
361 }
362
ClearTimer(const std::string & callbackId)363 void FrontendDelegateDeclarativeNG::ClearTimer(const std::string& callbackId)
364 {
365 auto timeoutTaskIter = timeoutTaskMap_.find(callbackId);
366 if (timeoutTaskIter != timeoutTaskMap_.end()) {
367 timeoutTaskIter->second.Cancel();
368 timeoutTaskMap_.erase(timeoutTaskIter);
369 } else {
370 LOGW("ClearTimer callbackId not found");
371 }
372 }
373
Push(const std::string & uri,const std::string & params)374 void FrontendDelegateDeclarativeNG::Push(const std::string& uri, const std::string& params)
375 {
376 CHECK_NULL_VOID(pageRouterManager_);
377 pageRouterManager_->Push(NG::RouterPageInfo({ uri, params }));
378 OnMediaQueryUpdate();
379 }
380
PushWithMode(const std::string & uri,const std::string & params,uint32_t routerMode)381 void FrontendDelegateDeclarativeNG::PushWithMode(const std::string& uri, const std::string& params, uint32_t routerMode)
382 {
383 CHECK_NULL_VOID(pageRouterManager_);
384 pageRouterManager_->Push(NG::RouterPageInfo({ uri, params, static_cast<NG::RouterMode>(routerMode) }));
385 OnMediaQueryUpdate();
386 }
387
PushWithCallback(const std::string & uri,const std::string & params,const std::function<void (const std::string &,int32_t)> & errorCallback,uint32_t routerMode)388 void FrontendDelegateDeclarativeNG::PushWithCallback(const std::string& uri, const std::string& params,
389 const std::function<void(const std::string&, int32_t)>& errorCallback, uint32_t routerMode)
390 {
391 CHECK_NULL_VOID(pageRouterManager_);
392 pageRouterManager_->Push(
393 NG::RouterPageInfo({ uri, params, static_cast<NG::RouterMode>(routerMode), errorCallback }));
394 OnMediaQueryUpdate();
395 }
396
PushNamedRoute(const std::string & uri,const std::string & params,const std::function<void (const std::string &,int32_t)> & errorCallback,uint32_t routerMode)397 void FrontendDelegateDeclarativeNG::PushNamedRoute(const std::string& uri, const std::string& params,
398 const std::function<void(const std::string&, int32_t)>& errorCallback, uint32_t routerMode)
399 {
400 CHECK_NULL_VOID(pageRouterManager_);
401 pageRouterManager_->PushNamedRoute(
402 NG::RouterPageInfo({ uri, params, static_cast<NG::RouterMode>(routerMode), errorCallback }));
403 OnMediaQueryUpdate();
404 }
405
Replace(const std::string & uri,const std::string & params)406 void FrontendDelegateDeclarativeNG::Replace(const std::string& uri, const std::string& params)
407 {
408 CHECK_NULL_VOID(pageRouterManager_);
409 pageRouterManager_->Replace(NG::RouterPageInfo({ uri, params }));
410 }
411
ReplaceWithMode(const std::string & uri,const std::string & params,uint32_t routerMode)412 void FrontendDelegateDeclarativeNG::ReplaceWithMode(
413 const std::string& uri, const std::string& params, uint32_t routerMode)
414 {
415 CHECK_NULL_VOID(pageRouterManager_);
416 pageRouterManager_->Replace(NG::RouterPageInfo({ uri, params, static_cast<NG::RouterMode>(routerMode) }));
417 OnMediaQueryUpdate();
418 }
419
ReplaceWithCallback(const std::string & uri,const std::string & params,const std::function<void (const std::string &,int32_t)> & errorCallback,uint32_t routerMode)420 void FrontendDelegateDeclarativeNG::ReplaceWithCallback(const std::string& uri, const std::string& params,
421 const std::function<void(const std::string&, int32_t)>& errorCallback, uint32_t routerMode)
422 {
423 CHECK_NULL_VOID(pageRouterManager_);
424 pageRouterManager_->Replace(
425 NG::RouterPageInfo({ uri, params, static_cast<NG::RouterMode>(routerMode), errorCallback }));
426 OnMediaQueryUpdate();
427 }
428
ReplaceNamedRoute(const std::string & uri,const std::string & params,const std::function<void (const std::string &,int32_t)> & errorCallback,uint32_t routerMode)429 void FrontendDelegateDeclarativeNG::ReplaceNamedRoute(const std::string& uri, const std::string& params,
430 const std::function<void(const std::string&, int32_t)>& errorCallback, uint32_t routerMode)
431 {
432 CHECK_NULL_VOID(pageRouterManager_);
433 pageRouterManager_->ReplaceNamedRoute(
434 NG::RouterPageInfo({ uri, params, static_cast<NG::RouterMode>(routerMode), errorCallback }));
435 OnMediaQueryUpdate();
436 }
437
Back(const std::string & uri,const std::string & params)438 void FrontendDelegateDeclarativeNG::Back(const std::string& uri, const std::string& params)
439 {
440 CHECK_NULL_VOID(pageRouterManager_);
441 pageRouterManager_->BackWithTarget(NG::RouterPageInfo({ uri, params }));
442 }
443
Clear()444 void FrontendDelegateDeclarativeNG::Clear()
445 {
446 CHECK_NULL_VOID(pageRouterManager_);
447 pageRouterManager_->Clear();
448 }
449
GetStackSize() const450 int32_t FrontendDelegateDeclarativeNG::GetStackSize() const
451 {
452 CHECK_NULL_RETURN(pageRouterManager_, 0);
453 return pageRouterManager_->GetStackSize();
454 }
455
GetState(int32_t & index,std::string & name,std::string & path)456 void FrontendDelegateDeclarativeNG::GetState(int32_t& index, std::string& name, std::string& path)
457 {
458 CHECK_NULL_VOID(pageRouterManager_);
459 pageRouterManager_->GetState(index, name, path);
460 }
461
GetParams()462 std::string FrontendDelegateDeclarativeNG::GetParams()
463 {
464 CHECK_NULL_RETURN(pageRouterManager_, "");
465 return pageRouterManager_->GetParams();
466 }
467
NavigatePage(uint8_t type,const PageTarget & target,const std::string & params)468 void FrontendDelegateDeclarativeNG::NavigatePage(uint8_t type, const PageTarget& target, const std::string& params)
469 {
470 switch (static_cast<NavigatorType>(type)) {
471 case NavigatorType::PUSH:
472 Push(target.url, params);
473 break;
474 case NavigatorType::REPLACE:
475 Replace(target.url, params);
476 break;
477 case NavigatorType::BACK:
478 Back(target.url, params);
479 break;
480 default:
481 LOGE("Navigator type is invalid!");
482 Back(target.url, params);
483 }
484 }
485
PostJsTask(std::function<void ()> && task)486 void FrontendDelegateDeclarativeNG::PostJsTask(std::function<void()>&& task)
487 {
488 taskExecutor_->PostTask(task, TaskExecutor::TaskType::JS);
489 }
490
GetAppID() const491 const std::string& FrontendDelegateDeclarativeNG::GetAppID() const
492 {
493 return manifestParser_->GetAppInfo()->GetAppID();
494 }
495
GetAppName() const496 const std::string& FrontendDelegateDeclarativeNG::GetAppName() const
497 {
498 return manifestParser_->GetAppInfo()->GetAppName();
499 }
500
GetVersionName() const501 const std::string& FrontendDelegateDeclarativeNG::GetVersionName() const
502 {
503 return manifestParser_->GetAppInfo()->GetVersionName();
504 }
505
GetVersionCode() const506 int32_t FrontendDelegateDeclarativeNG::GetVersionCode() const
507 {
508 return manifestParser_->GetAppInfo()->GetVersionCode();
509 }
510
PostSyncTaskToPage(std::function<void ()> && task)511 void FrontendDelegateDeclarativeNG::PostSyncTaskToPage(std::function<void()>&& task)
512 {
513 pipelineContextHolder_.Get(); // Wait until Pipeline Context is attached.
514 taskExecutor_->PostSyncTask(task, TaskExecutor::TaskType::UI);
515 }
516
GetAssetContent(const std::string & url,std::string & content)517 bool FrontendDelegateDeclarativeNG::GetAssetContent(const std::string& url, std::string& content)
518 {
519 return GetAssetContentImpl(assetManager_, url, content);
520 }
521
GetAssetContent(const std::string & url,std::vector<uint8_t> & content)522 bool FrontendDelegateDeclarativeNG::GetAssetContent(const std::string& url, std::vector<uint8_t>& content)
523 {
524 return GetAssetContentImpl(assetManager_, url, content);
525 }
526
GetAssetPath(const std::string & url)527 std::string FrontendDelegateDeclarativeNG::GetAssetPath(const std::string& url)
528 {
529 return GetAssetPathImpl(assetManager_, url);
530 }
531
ChangeLocale(const std::string & language,const std::string & countryOrRegion)532 void FrontendDelegateDeclarativeNG::ChangeLocale(const std::string& language, const std::string& countryOrRegion)
533 {
534 LOGD("JSFrontend ChangeLocale");
535 taskExecutor_->PostTask(
536 [language, countryOrRegion]() { AceApplicationInfo::GetInstance().ChangeLocale(language, countryOrRegion); },
537 TaskExecutor::TaskType::PLATFORM);
538 }
539
RegisterFont(const std::string & familyName,const std::string & familySrc)540 void FrontendDelegateDeclarativeNG::RegisterFont(const std::string& familyName, const std::string& familySrc)
541 {
542 pipelineContextHolder_.Get()->RegisterFont(familyName, familySrc);
543 }
544
GetSystemFontList(std::vector<std::string> & fontList)545 void FrontendDelegateDeclarativeNG::GetSystemFontList(std::vector<std::string>& fontList)
546 {
547 pipelineContextHolder_.Get()->GetSystemFontList(fontList);
548 }
549
GetSystemFont(const std::string & fontName,FontInfo & fontInfo)550 bool FrontendDelegateDeclarativeNG::GetSystemFont(const std::string& fontName, FontInfo& fontInfo)
551 {
552 return pipelineContextHolder_.Get()->GetSystemFont(fontName, fontInfo);
553 }
554
MeasureText(const MeasureContext & context)555 double FrontendDelegateDeclarativeNG::MeasureText(const MeasureContext& context)
556 {
557 return MeasureUtil::MeasureText(context);
558 }
559
MeasureTextSize(const MeasureContext & context)560 Size FrontendDelegateDeclarativeNG::MeasureTextSize(const MeasureContext& context)
561 {
562 return MeasureUtil::MeasureTextSize(context);
563 }
564
GetAnimationJsTask()565 SingleTaskExecutor FrontendDelegateDeclarativeNG::GetAnimationJsTask()
566 {
567 return SingleTaskExecutor::Make(taskExecutor_, TaskExecutor::TaskType::JS);
568 }
569
GetUiTask()570 SingleTaskExecutor FrontendDelegateDeclarativeNG::GetUiTask()
571 {
572 return SingleTaskExecutor::Make(taskExecutor_, TaskExecutor::TaskType::UI);
573 }
574
GetPipelineContext()575 RefPtr<PipelineBase> FrontendDelegateDeclarativeNG::GetPipelineContext()
576 {
577 return pipelineContextHolder_.Get();
578 }
579
OnPageBackPress()580 bool FrontendDelegateDeclarativeNG::OnPageBackPress()
581 {
582 CHECK_NULL_RETURN(pageRouterManager_, false);
583 auto pageNode = pageRouterManager_->GetCurrentPageNode();
584 CHECK_NULL_RETURN(pageNode, false);
585 auto pagePattern = pageNode->GetPattern<NG::PagePattern>();
586 CHECK_NULL_RETURN(pagePattern, false);
587 if (pagePattern->OnBackPressed()) {
588 return true;
589 }
590 return pageRouterManager_->Pop();
591 }
592
OnSurfaceChanged()593 void FrontendDelegateDeclarativeNG::OnSurfaceChanged()
594 {
595 if (mediaQueryInfo_->GetIsInit()) {
596 mediaQueryInfo_->SetIsInit(false);
597 }
598 mediaQueryInfo_->EnsureListenerIdValid();
599 OnMediaQueryUpdate();
600 }
601
ShowDialog(const std::string & title,const std::string & message,const std::vector<ButtonInfo> & buttons,bool autoCancel,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)602 void FrontendDelegateDeclarativeNG::ShowDialog(const std::string& title, const std::string& message,
603 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
604 const std::set<std::string>& callbacks)
605 {
606 DialogProperties dialogProperties = {
607 .title = title,
608 .content = message,
609 .autoCancel = autoCancel,
610 .buttons = buttons,
611 };
612 ShowDialogInner(dialogProperties, std::move(callback), callbacks);
613 }
614
ShowDialog(const std::string & title,const std::string & message,const std::vector<ButtonInfo> & buttons,bool autoCancel,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks,std::function<void (bool)> && onStatusChanged)615 void FrontendDelegateDeclarativeNG::ShowDialog(const std::string& title, const std::string& message,
616 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& callback,
617 const std::set<std::string>& callbacks, std::function<void(bool)>&& onStatusChanged)
618 {
619 DialogProperties dialogProperties = {
620 .title = title,
621 .content = message,
622 .autoCancel = autoCancel,
623 .buttons = buttons,
624 .onStatusChanged = std::move(onStatusChanged),
625 };
626 ShowDialogInner(dialogProperties, std::move(callback), callbacks);
627 }
628
ShowDialog(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)629 void FrontendDelegateDeclarativeNG::ShowDialog(const PromptDialogAttr& dialogAttr,
630 const std::vector<ButtonInfo>& buttons, std::function<void(int32_t, int32_t)>&& callback,
631 const std::set<std::string>& callbacks)
632 {
633 DialogProperties dialogProperties = {
634 .title = dialogAttr.title,
635 .content = dialogAttr.message,
636 .autoCancel = dialogAttr.autoCancel,
637 .buttons = buttons,
638 .maskRect = dialogAttr.maskRect,
639 };
640 if (dialogAttr.alignment.has_value()) {
641 dialogProperties.alignment = dialogAttr.alignment.value();
642 }
643 if (dialogAttr.offset.has_value()) {
644 dialogProperties.offset = dialogAttr.offset.value();
645 }
646 ShowDialogInner(dialogProperties, std::move(callback), callbacks);
647 }
648
ShowDialog(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks,std::function<void (bool)> && onStatusChanged)649 void FrontendDelegateDeclarativeNG::ShowDialog(const PromptDialogAttr& dialogAttr,
650 const std::vector<ButtonInfo>& buttons, std::function<void(int32_t, int32_t)>&& callback,
651 const std::set<std::string>& callbacks, std::function<void(bool)>&& onStatusChanged)
652 {
653 DialogProperties dialogProperties = {
654 .title = dialogAttr.title,
655 .content = dialogAttr.message,
656 .autoCancel = dialogAttr.autoCancel,
657 .buttons = buttons,
658 .onStatusChanged = std::move(onStatusChanged),
659 .maskRect = dialogAttr.maskRect,
660 };
661 if (dialogAttr.alignment.has_value()) {
662 dialogProperties.alignment = dialogAttr.alignment.value();
663 }
664 if (dialogAttr.offset.has_value()) {
665 dialogProperties.offset = dialogAttr.offset.value();
666 }
667 ShowDialogInner(dialogProperties, std::move(callback), callbacks);
668 }
669
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)670 void FrontendDelegateDeclarativeNG::ShowActionMenu(
671 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
672 {
673 DialogProperties dialogProperties = {
674 .title = title,
675 .autoCancel = true,
676 .isMenu = true,
677 .buttons = button,
678 };
679 ShowActionMenuInner(dialogProperties, button, std::move(callback));
680 }
681
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback,std::function<void (bool)> && onStatusChanged)682 void FrontendDelegateDeclarativeNG::ShowActionMenu(const std::string& title, const std::vector<ButtonInfo>& button,
683 std::function<void(int32_t, int32_t)>&& callback, std::function<void(bool)>&& onStatusChanged)
684 {
685 DialogProperties dialogProperties = {
686 .title = title,
687 .autoCancel = true,
688 .isMenu = true,
689 .buttons = button,
690 .onStatusChanged = std::move(onStatusChanged),
691 };
692 ShowActionMenuInner(dialogProperties, button, std::move(callback));
693 }
694
OnMediaQueryUpdate(bool isSynchronous)695 void FrontendDelegateDeclarativeNG::OnMediaQueryUpdate(bool isSynchronous)
696 {
697 auto containerId = Container::CurrentId();
698 if (containerId < 0) {
699 auto container = Container::GetActive();
700 if (container) {
701 containerId = container->GetInstanceId();
702 }
703 }
704 bool isInSubwindow = containerId >= 1000000;
705 if (isInSubwindow) {
706 return;
707 }
708 if (mediaQueryInfo_->GetIsInit()) {
709 return;
710 }
711
712 taskExecutor_->PostTask(
713 [weak = AceType::WeakClaim(this)] {
714 auto delegate = weak.Upgrade();
715 if (!delegate) {
716 return;
717 }
718 const auto& info = delegate->mediaQueryInfo_->GetMediaQueryInfo();
719
720 // request js media query
721 const auto& listenerId = delegate->mediaQueryInfo_->GetListenerId();
722 delegate->mediaQueryCallback_(listenerId, info);
723 delegate->mediaQueryInfo_->ResetListenerId();
724 },
725 TaskExecutor::TaskType::JS);
726 }
727
OnLayoutCompleted(const std::string & componentId)728 void FrontendDelegateDeclarativeNG::OnLayoutCompleted(const std::string& componentId)
729 {
730 taskExecutor_->PostTask(
731 [weak = AceType::WeakClaim(this), componentId] {
732 auto delegate = weak.Upgrade();
733 if (!delegate) {
734 return;
735 }
736 delegate->layoutInspectorCallback_(componentId);
737 },
738 TaskExecutor::TaskType::JS);
739 }
740
OnDrawCompleted(const std::string & componentId)741 void FrontendDelegateDeclarativeNG::OnDrawCompleted(const std::string& componentId)
742 {
743 taskExecutor_->PostTask(
744 [weak = AceType::WeakClaim(this), componentId] {
745 auto delegate = weak.Upgrade();
746 if (!delegate) {
747 return;
748 }
749 delegate->drawInspectorCallback_(componentId);
750 },
751 TaskExecutor::TaskType::JS);
752 }
753
SetColorMode(ColorMode colorMode)754 void FrontendDelegateDeclarativeNG::SetColorMode(ColorMode colorMode)
755 {
756 OnMediaQueryUpdate();
757 }
758
OnForeground()759 void FrontendDelegateDeclarativeNG::OnForeground()
760 {
761 if (!isFirstNotifyShow_) {
762 OnPageShow();
763 }
764 isFirstNotifyShow_ = false;
765 }
766
GetCurrentPageUrl()767 std::string FrontendDelegateDeclarativeNG::GetCurrentPageUrl()
768 {
769 CHECK_NULL_RETURN(pageRouterManager_, "");
770 return pageRouterManager_->GetCurrentPageUrl();
771 }
772
773 // Get the currently running JS page information in NG structure.
GetCurrentPageSourceMap()774 RefPtr<RevSourceMap> FrontendDelegateDeclarativeNG::GetCurrentPageSourceMap()
775 {
776 CHECK_NULL_RETURN(pageRouterManager_, nullptr);
777 return pageRouterManager_->GetCurrentPageSourceMap(assetManager_);
778 }
779
780 // Get the currently running JS page information in NG structure.
GetFaAppSourceMap()781 RefPtr<RevSourceMap> FrontendDelegateDeclarativeNG::GetFaAppSourceMap()
782 {
783 if (appSourceMap_) {
784 return appSourceMap_;
785 }
786 std::string appMap;
787 if (GetAssetContent("app.js.map", appMap)) {
788 appSourceMap_ = AceType::MakeRefPtr<RevSourceMap>();
789 appSourceMap_->Init(appMap);
790 } else {
791 LOGW("app map load failed!");
792 }
793 return appSourceMap_;
794 }
795
GetStageSourceMap(std::unordered_map<std::string,RefPtr<Framework::RevSourceMap>> & sourceMaps)796 void FrontendDelegateDeclarativeNG::GetStageSourceMap(
797 std::unordered_map<std::string, RefPtr<Framework::RevSourceMap>>& sourceMaps)
798 {
799 std::string maps;
800 if (GetAssetContent(MERGE_SOURCEMAPS_PATH, maps)) {
801 auto SourceMap = AceType::MakeRefPtr<RevSourceMap>();
802 SourceMap->StageModeSourceMapSplit(maps, sourceMaps);
803 } else {
804 LOGW("app map load failed!");
805 }
806 }
807
CallPopPage()808 void FrontendDelegateDeclarativeNG::CallPopPage()
809 {
810 LOGI("CallPopPage begin");
811 Back("", "");
812 }
813
PostponePageTransition()814 void FrontendDelegateDeclarativeNG::PostponePageTransition()
815 {
816 taskExecutor_->PostTask(
817 [weak = AceType::WeakClaim(this)] {
818 auto delegate = weak.Upgrade();
819 if (!delegate) {
820 return;
821 }
822 auto pipelineContext = delegate->pipelineContextHolder_.Get();
823 pipelineContext->PostponePageTransition();
824 },
825 TaskExecutor::TaskType::UI);
826 }
827
LaunchPageTransition()828 void FrontendDelegateDeclarativeNG::LaunchPageTransition()
829 {
830 taskExecutor_->PostTask(
831 [weak = AceType::WeakClaim(this)] {
832 auto delegate = weak.Upgrade();
833 if (!delegate) {
834 return;
835 }
836 auto pipelineContext = delegate->pipelineContextHolder_.Get();
837 pipelineContext->LaunchPageTransition();
838 },
839 TaskExecutor::TaskType::UI);
840 }
841
GetComponentsCount()842 size_t FrontendDelegateDeclarativeNG::GetComponentsCount()
843 {
844 CHECK_NULL_RETURN(pageRouterManager_, 0);
845 auto pageNode = pageRouterManager_->GetCurrentPageNode();
846 CHECK_NULL_RETURN(pageNode, 0);
847 return pageNode->GetAllDepthChildrenCount();
848 }
849
ShowToast(const std::string & message,int32_t duration,const std::string & bottom)850 void FrontendDelegateDeclarativeNG::ShowToast(const std::string& message, int32_t duration, const std::string& bottom)
851 {
852 LOGD("FrontendDelegateDeclarativeNG ShowToast.");
853
854 int32_t durationTime = std::clamp(duration, TOAST_TIME_DEFAULT, TOAST_TIME_MAX);
855 bool isRightToLeft = AceApplicationInfo::GetInstance().IsRightToLeft();
856 auto task = [durationTime, message, bottom, isRightToLeft, containerId = Container::CurrentId()](
857 const RefPtr<NG::OverlayManager>& overlayManager) {
858 CHECK_NULL_VOID(overlayManager);
859 ContainerScope scope(containerId);
860 LOGI("Begin to show toast message %{public}s, duration is %{public}d", message.c_str(), durationTime);
861 overlayManager->ShowToast(message, durationTime, bottom, isRightToLeft);
862 };
863 MainWindowOverlay(std::move(task));
864 return;
865 }
866
ShowDialogInner(DialogProperties & dialogProperties,std::function<void (int32_t,int32_t)> && callback,const std::set<std::string> & callbacks)867 void FrontendDelegateDeclarativeNG::ShowDialogInner(DialogProperties& dialogProperties,
868 std::function<void(int32_t, int32_t)>&& callback, const std::set<std::string>& callbacks)
869 {
870 dialogProperties.onSuccess = std::move(callback);
871 dialogProperties.onCancel = [callback, taskExecutor = taskExecutor_] {
872 taskExecutor->PostTask(
873 [callback]() { callback(CALLBACK_ERRORCODE_CANCEL, CALLBACK_DATACODE_ZERO); }, TaskExecutor::TaskType::JS);
874 };
875 auto task = [dialogProperties](const RefPtr<NG::OverlayManager>& overlayManager) {
876 CHECK_NULL_VOID(overlayManager);
877 LOGI("Begin to show dialog ");
878 overlayManager->ShowDialog(dialogProperties, nullptr, AceApplicationInfo::GetInstance().IsRightToLeft());
879 };
880 MainWindowOverlay(std::move(task));
881 return;
882 }
883
ShowActionMenuInner(DialogProperties & dialogProperties,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)884 void FrontendDelegateDeclarativeNG::ShowActionMenuInner(DialogProperties& dialogProperties,
885 const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
886 {
887 ButtonInfo buttonInfo = { .text = Localization::GetInstance()->GetEntryLetters("common.cancel"), .textColor = "" };
888 dialogProperties.buttons.emplace_back(buttonInfo);
889 dialogProperties.onSuccess = std::move(callback);
890 dialogProperties.onCancel = [callback, taskExecutor = taskExecutor_] {
891 taskExecutor->PostTask(
892 [callback]() { callback(CALLBACK_ERRORCODE_CANCEL, CALLBACK_DATACODE_ZERO); }, TaskExecutor::TaskType::JS);
893 };
894 auto context = DynamicCast<NG::PipelineContext>(pipelineContextHolder_.Get());
895 auto overlayManager = context ? context->GetOverlayManager() : nullptr;
896 taskExecutor_->PostTask(
897 [dialogProperties, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
898 auto overlayManager = weak.Upgrade();
899 CHECK_NULL_VOID(overlayManager);
900 overlayManager->ShowDialog(dialogProperties, nullptr, AceApplicationInfo::GetInstance().IsRightToLeft());
901 },
902 TaskExecutor::TaskType::UI);
903 return;
904 }
905
EnableAlertBeforeBackPage(const std::string & message,std::function<void (int32_t)> && callback)906 void FrontendDelegateDeclarativeNG::EnableAlertBeforeBackPage(
907 const std::string& message, std::function<void(int32_t)>&& callback)
908 {
909 CHECK_NULL_VOID(pageRouterManager_);
910 pageRouterManager_->EnableAlertBeforeBackPage(message, std::move(callback));
911 return;
912 }
913
DisableAlertBeforeBackPage()914 void FrontendDelegateDeclarativeNG::DisableAlertBeforeBackPage()
915 {
916 CHECK_NULL_VOID(pageRouterManager_);
917 pageRouterManager_->DisableAlertBeforeBackPage();
918 return;
919 }
920
RebuildAllPages()921 void FrontendDelegateDeclarativeNG::RebuildAllPages()
922 {
923 CHECK_NULL_VOID(pageRouterManager_);
924 auto url = pageRouterManager_->GetCurrentPageUrl();
925 pageRouterManager_->Clear();
926 pageRouterManager_->RunPage(url, "");
927 return;
928 }
929
OnPageShow()930 void FrontendDelegateDeclarativeNG::OnPageShow()
931 {
932 CHECK_NULL_VOID(pageRouterManager_);
933 auto pageNode = pageRouterManager_->GetCurrentPageNode();
934 CHECK_NULL_VOID(pageNode);
935 auto pagePattern = pageNode->GetPattern<NG::PagePattern>();
936 CHECK_NULL_VOID(pagePattern);
937 pagePattern->OnShow();
938 }
939
OnPageHide()940 void FrontendDelegateDeclarativeNG::OnPageHide()
941 {
942 CHECK_NULL_VOID(pageRouterManager_);
943 auto pageNode = pageRouterManager_->GetCurrentPageNode();
944 CHECK_NULL_VOID(pageNode);
945 auto pagePattern = pageNode->GetPattern<NG::PagePattern>();
946 CHECK_NULL_VOID(pagePattern);
947 pagePattern->OnHide();
948 }
949
GetSnapshot(const std::string & componentId,NG::ComponentSnapshot::JsCallback && callback)950 void FrontendDelegateDeclarativeNG::GetSnapshot(
951 const std::string& componentId, NG::ComponentSnapshot::JsCallback&& callback)
952 {
953 #ifdef ENABLE_ROSEN_BACKEND
954 NG::ComponentSnapshot::Get(componentId, std::move(callback));
955 #endif
956 }
957
GetContentInfo()958 std::string FrontendDelegateDeclarativeNG::GetContentInfo()
959 {
960 auto jsonContentInfo = JsonUtil::Create(true);
961 auto pipelineContext = pipelineContextHolder_.Get();
962 CHECK_NULL_RETURN(pipelineContext, jsonContentInfo->ToString());
963 jsonContentInfo->Put("nodeInfo", pipelineContext->GetStoredNodeInfo());
964
965 return jsonContentInfo->ToString();
966 }
967
CreateSnapshot(std::function<void ()> && customBuilder,NG::ComponentSnapshot::JsCallback && callback)968 void FrontendDelegateDeclarativeNG::CreateSnapshot(
969 std::function<void()>&& customBuilder, NG::ComponentSnapshot::JsCallback&& callback)
970 {
971 #ifdef ENABLE_ROSEN_BACKEND
972 ViewStackModel::GetInstance()->NewScope();
973 CHECK_NULL_VOID(customBuilder);
974 customBuilder();
975 auto customNode = ViewStackModel::GetInstance()->Finish();
976
977 NG::ComponentSnapshot::Create(customNode, std::move(callback));
978 #endif
979 }
980
981 } // namespace OHOS::Ace::Framework
982