• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "frameworks/bridge/declarative_frontend/ng/declarative_frontend_ng.h"
17 
18 #include "base/log/dump_log.h"
19 #include "core/common/thread_checker.h"
20 #include "frameworks/bridge/common/utils/utils.h"
21 
22 namespace OHOS::Ace {
23 
~DeclarativeFrontendNG()24 DeclarativeFrontendNG::~DeclarativeFrontendNG() noexcept
25 {
26     LOG_DESTROY();
27 }
28 
Destroy()29 void DeclarativeFrontendNG::Destroy()
30 {
31     CHECK_RUN_ON(JS);
32     LOGI("DeclarativeFrontendNG Destroy begin.");
33     // To guarantee the jsEngine_ and delegate_ released in js thread
34     delegate_.Reset();
35     jsEngine_->Destroy();
36     jsEngine_.Reset();
37     LOGI("DeclarativeFrontendNG Destroy end.");
38 }
39 
Initialize(FrontendType type,const RefPtr<TaskExecutor> & taskExecutor)40 bool DeclarativeFrontendNG::Initialize(FrontendType type, const RefPtr<TaskExecutor>& taskExecutor)
41 {
42     LOGI("DeclarativeFrontendNG initialize begin.");
43     type_ = type;
44     taskExecutor_ = taskExecutor;
45     ACE_DCHECK(type_ == FrontendType::DECLARATIVE_JS);
46     InitializeDelegate(taskExecutor);
47     bool needPostJsTask = true;
48     auto container = Container::Current();
49     if (container) {
50         const auto& setting = container->GetSettings();
51         needPostJsTask = !(setting.usePlatformAsUIThread && setting.useUIAsJSThread);
52     }
53     auto initJSEngineTask = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_), delegate = delegate_] {
54         auto jsEngine = weakEngine.Upgrade();
55         if (!jsEngine) {
56             return;
57         }
58         jsEngine->Initialize(delegate);
59     };
60     if (needPostJsTask) {
61         taskExecutor->PostTask(initJSEngineTask, TaskExecutor::TaskType::JS);
62     } else {
63         initJSEngineTask();
64     }
65     LOGI("DeclarativeFrontendNG initialize end.");
66     return true;
67 }
68 
AttachPipelineContext(const RefPtr<PipelineBase> & context)69 void DeclarativeFrontendNG::AttachPipelineContext(const RefPtr<PipelineBase>& context)
70 {
71     LOGI("DeclarativeFrontendNG AttachPipelineContext.");
72     if (delegate_) {
73         delegate_->AttachPipelineContext(context);
74     }
75 }
76 
AttachSubPipelineContext(const RefPtr<PipelineContext> & context)77 void DeclarativeFrontendNG::AttachSubPipelineContext(const RefPtr<PipelineContext>& context)
78 {
79     LOGI("DeclarativeFrontendNG AttachSubPipelineContext.");
80     if (!delegate_) {
81         return;
82     }
83     delegate_->AttachSubPipelineContext(context);
84 }
85 
SetAssetManager(const RefPtr<AssetManager> & assetManager)86 void DeclarativeFrontendNG::SetAssetManager(const RefPtr<AssetManager>& assetManager)
87 {
88     LOGI("DeclarativeFrontendNG SetAssetManager.");
89     if (delegate_) {
90         delegate_->SetAssetManager(assetManager);
91     }
92 }
93 
InitializeDelegate(const RefPtr<TaskExecutor> & taskExecutor)94 void DeclarativeFrontendNG::InitializeDelegate(const RefPtr<TaskExecutor>& taskExecutor)
95 {
96     auto pageRouterManager = AceType::MakeRefPtr<NG::PageRouterManager>();
97     auto loadPageCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](const std::string& url,
98                                 const std::function<void(const std::string&, int32_t)>& errorCallback) {
99         auto jsEngine = weakEngine.Upgrade();
100         if (!jsEngine) {
101             return false;
102         }
103         return jsEngine->LoadPageSource(url, errorCallback);
104     };
105 
106     auto mediaQueryCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
107                                          const std::string& callbackId, const std::string& args) {
108         auto jsEngine = weakEngine.Upgrade();
109         if (!jsEngine) {
110             return;
111         }
112         jsEngine->MediaQueryCallback(callbackId, args);
113     };
114 
115     auto layoutInspectorCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
116                                        const std::string& componentId) {
117         auto jsEngine = weakEngine.Upgrade();
118         if (!jsEngine) {
119             return;
120         }
121         jsEngine->LayoutInspectorCallback(componentId);
122     };
123 
124     auto drawInspectorCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
125                                      const std::string& componentId) {
126         auto jsEngine = weakEngine.Upgrade();
127         if (!jsEngine) {
128             return;
129         }
130         jsEngine->DrawInspectorCallback(componentId);
131     };
132 
133     auto onStartContinuationCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)]() -> bool {
134         auto jsEngine = weakEngine.Upgrade();
135         if (!jsEngine) {
136             return false;
137         }
138         return jsEngine->OnStartContinuation();
139     };
140 
141     auto onCompleteContinuationCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](int32_t code) {
142         auto jsEngine = weakEngine.Upgrade();
143         if (!jsEngine) {
144             return;
145         }
146         jsEngine->OnCompleteContinuation(code);
147     };
148 
149     auto onSaveDataCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](std::string& savedData) {
150         auto jsEngine = weakEngine.Upgrade();
151         if (!jsEngine) {
152             return;
153         }
154         jsEngine->OnSaveData(savedData);
155     };
156 
157     auto onRemoteTerminatedCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)]() {
158         auto jsEngine = weakEngine.Upgrade();
159         if (!jsEngine) {
160             return;
161         }
162         jsEngine->OnRemoteTerminated();
163     };
164 
165     auto onRestoreDataCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
166                                             const std::string& data) -> bool {
167         auto jsEngine = weakEngine.Upgrade();
168         if (!jsEngine) {
169             return false;
170         }
171         return jsEngine->OnRestoreData(data);
172     };
173 
174     auto destroyApplicationCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
175                                                  const std::string& packageName) {
176         auto jsEngine = weakEngine.Upgrade();
177         if (!jsEngine) {
178             return;
179         }
180         jsEngine->DestroyApplication(packageName);
181     };
182 
183     auto updateApplicationStateCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
184                                                      const std::string& packageName, Frontend::State state) {
185         auto jsEngine = weakEngine.Upgrade();
186         if (!jsEngine) {
187             return;
188         }
189         jsEngine->UpdateApplicationState(packageName, state);
190     };
191 
192     auto onWindowDisplayModeChangedCallBack = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
193                                                          bool isShownInMultiWindow, const std::string& data) {
194         auto jsEngine = weakEngine.Upgrade();
195         if (!jsEngine) {
196             return;
197         }
198         jsEngine->OnWindowDisplayModeChanged(isShownInMultiWindow, data);
199     };
200 
201     auto externalEventCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
202                                             const std::string& componentId, const uint32_t nodeId,
203                                             const bool isDestroy) {
204         auto jsEngine = weakEngine.Upgrade();
205         if (!jsEngine) {
206             return;
207         }
208         jsEngine->FireExternalEvent(componentId, nodeId, isDestroy);
209     };
210 
211     auto timerCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
212                                     const std::string& callbackId, const std::string& delay, bool isInterval) {
213         auto jsEngine = weakEngine.Upgrade();
214         if (!jsEngine) {
215             return;
216         }
217         jsEngine->TimerCallback(callbackId, delay, isInterval);
218     };
219 
220     auto loadNamedRouterCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](
221                                        const std::string& namedRouter, bool isTriggeredByJs) {
222         auto jsEngine = weakEngine.Upgrade();
223         if (!jsEngine) {
224             return false;
225         }
226         return jsEngine->LoadNamedRouterSource(namedRouter, isTriggeredByJs);
227     };
228 
229     pageRouterManager->SetLoadJsCallback(std::move(loadPageCallback));
230     pageRouterManager->SetLoadNamedRouterCallback(std::move(loadNamedRouterCallback));
231 
232     delegate_ = AceType::MakeRefPtr<Framework::FrontendDelegateDeclarativeNG>(taskExecutor);
233     delegate_->SetMediaQueryCallback(std::move(mediaQueryCallback));
234     delegate_->SetLayoutInspectorCallback(std::move(layoutInspectorCallback));
235     delegate_->SetDrawInspectorCallback(std::move(drawInspectorCallback));
236     delegate_->SetOnStartContinuationCallBack(std::move(onStartContinuationCallBack));
237     delegate_->SetOnCompleteContinuationCallBack(std::move(onCompleteContinuationCallBack));
238     delegate_->SetOnSaveDataCallBack(std::move(onSaveDataCallBack));
239     delegate_->SetOnRemoteTerminatedCallBack(std::move(onRemoteTerminatedCallBack));
240     delegate_->SetOnRestoreDataCallBack(std::move(onRestoreDataCallBack));
241     delegate_->SetDestroyApplicationCallback(std::move(destroyApplicationCallback));
242     delegate_->SetUpdateApplicationStateCallback(std::move(updateApplicationStateCallback));
243     delegate_->SetOnWindowDisplayModeChangedCallback(std::move(onWindowDisplayModeChangedCallBack));
244     delegate_->SetExternalEventCallback(std::move(externalEventCallback));
245     delegate_->SetTimerCallback(std::move(timerCallback));
246 
247     delegate_->SetPageRouterManager(pageRouterManager);
248     if (jsEngine_) {
249         delegate_->SetGroupJsBridge(jsEngine_->GetGroupJsBridge());
250     }
251 }
252 
GetPageRouterManager() const253 RefPtr<NG::PageRouterManager> DeclarativeFrontendNG::GetPageRouterManager() const
254 {
255     CHECK_NULL_RETURN(delegate_, nullptr);
256     return delegate_->GetPageRouterManager();
257 }
258 
UpdateState(Frontend::State state)259 void DeclarativeFrontendNG::UpdateState(Frontend::State state)
260 {
261     if (!delegate_ || state == Frontend::State::ON_CREATE) {
262         return;
263     }
264     bool needPostJsTask = true;
265     auto container = Container::Current();
266     CHECK_NULL_VOID(container);
267     const auto& setting = container->GetSettings();
268     needPostJsTask = !(setting.usePlatformAsUIThread && setting.useUIAsJSThread);
269     if (needPostJsTask) {
270         delegate_->UpdateApplicationState(delegate_->GetAppID(), state);
271         return;
272     }
273     if (jsEngine_) {
274         jsEngine_->UpdateApplicationState(delegate_->GetAppID(), state);
275     }
276 }
277 
OnConfigurationUpdated(const std::string & data)278 void DeclarativeFrontendNG::OnConfigurationUpdated(const std::string& data)
279 {
280     if (delegate_) {
281         delegate_->OnConfigurationUpdated(data);
282     }
283 }
284 
OnActive()285 void DeclarativeFrontendNG::OnActive()
286 {
287     if (delegate_) {
288         foregroundFrontend_ = true;
289         delegate_->InitializeAccessibilityCallback();
290     }
291 }
292 
OnCompleteContinuation(int32_t code)293 void DeclarativeFrontendNG::OnCompleteContinuation(int32_t code)
294 {
295     if (delegate_) {
296         delegate_->OnCompleteContinuation(code);
297     }
298 }
299 
OnSaveData(std::string & data)300 void DeclarativeFrontendNG::OnSaveData(std::string& data)
301 {
302     if (delegate_) {
303         delegate_->OnSaveData(data);
304     }
305 }
306 
OnRemoteTerminated()307 void DeclarativeFrontendNG::OnRemoteTerminated()
308 {
309     if (delegate_) {
310         delegate_->OnRemoteTerminated();
311     }
312 }
313 
NotifyAppStorage(const std::string & key,const std::string & value)314 void DeclarativeFrontendNG::NotifyAppStorage(const std::string& key, const std::string& value)
315 {
316     if (!delegate_) {
317         LOGW("delegate is null, return false");
318         return;
319     }
320     delegate_->NotifyAppStorage(jsEngine_, key, value);
321 }
322 
GetRouterSize() const323 int32_t DeclarativeFrontendNG::GetRouterSize() const
324 {
325     if (delegate_) {
326         return delegate_->GetStackSize();
327     }
328     return -1;
329 }
330 
OnStartContinuation()331 bool DeclarativeFrontendNG::OnStartContinuation()
332 {
333     if (!delegate_) {
334         LOGW("delegate is null, return false");
335         return false;
336     }
337     return delegate_->OnStartContinuation();
338 }
339 
OnRestoreData(const std::string & data)340 bool DeclarativeFrontendNG::OnRestoreData(const std::string& data)
341 {
342     if (!delegate_) {
343         LOGW("delegate is null, return false");
344         return false;
345     }
346     return delegate_->OnRestoreData(data);
347 }
348 
RunPage(int32_t pageId,const std::string & url,const std::string & params)349 void DeclarativeFrontendNG::RunPage(int32_t pageId, const std::string& url, const std::string& params)
350 {
351     auto container = Container::Current();
352     auto isStageModel = container ? container->IsUseStageModel() : false;
353     if (!isStageModel) {
354         // In NG structure and fa mode, first load app.js
355         auto taskExecutor = container ? container->GetTaskExecutor() : nullptr;
356         CHECK_NULL_VOID(taskExecutor);
357         taskExecutor->PostTask(
358             [weak = AceType::WeakClaim(this)]() {
359                 auto frontend = weak.Upgrade();
360                 CHECK_NULL_VOID(frontend);
361                 CHECK_NULL_VOID(frontend->jsEngine_);
362                 frontend->jsEngine_->LoadFaAppSource();
363             },
364             TaskExecutor::TaskType::JS);
365     }
366     // Not use this pageId from backend, manage it in FrontendDelegateDeclarativeNg.
367     if (delegate_) {
368         delegate_->RunPage(url, params, pageProfile_);
369     }
370 }
371 
ReplacePage(const std::string & url,const std::string & params)372 void DeclarativeFrontendNG::ReplacePage(const std::string& url, const std::string& params)
373 {
374     if (delegate_) {
375         delegate_->Replace(url, params);
376     }
377 }
378 
PushPage(const std::string & url,const std::string & params)379 void DeclarativeFrontendNG::PushPage(const std::string& url, const std::string& params)
380 {
381     if (delegate_) {
382         delegate_->Push(url, params);
383     }
384 }
385 
386 
GetContextValue()387 NativeValue* DeclarativeFrontendNG::GetContextValue()
388 {
389     return jsEngine_->GetContextValue();
390 }
391 
NavigatePage(uint8_t type,const PageTarget & target,const std::string & params)392 void DeclarativeFrontendNG::NavigatePage(uint8_t type, const PageTarget& target, const std::string& params)
393 {
394     if (delegate_) {
395         delegate_->NavigatePage(type, target, params);
396     }
397 }
398 
OnWindowDisplayModeChanged(bool isShownInMultiWindow,const std::string & data)399 void DeclarativeFrontendNG::OnWindowDisplayModeChanged(bool isShownInMultiWindow, const std::string& data)
400 {
401     LOGW("OnWindowDisplayModeChanged not implemented");
402     delegate_->OnWindowDisplayModeChanged(isShownInMultiWindow, data);
403 }
404 
GetAccessibilityManager() const405 RefPtr<AccessibilityManager> DeclarativeFrontendNG::GetAccessibilityManager() const
406 {
407     if (!delegate_) {
408         LOGE("GetAccessibilityManager delegate is null");
409         return nullptr;
410     }
411     return delegate_->GetJSAccessibilityManager();
412 }
413 
GetWindowConfig()414 WindowConfig& DeclarativeFrontendNG::GetWindowConfig()
415 {
416     if (!delegate_) {
417         static WindowConfig windowConfig;
418         LOGW("delegate is null, return default config");
419         return windowConfig;
420     }
421     return delegate_->GetWindowConfig();
422 }
423 
OnBackPressed()424 bool DeclarativeFrontendNG::OnBackPressed()
425 {
426     CHECK_NULL_RETURN(delegate_, false);
427     return delegate_->OnPageBackPress();
428 }
429 
OnShow()430 void DeclarativeFrontendNG::OnShow()
431 {
432     foregroundFrontend_ = true;
433     CHECK_NULL_VOID(delegate_);
434     delegate_->OnPageShow();
435 }
436 
OnHide()437 void DeclarativeFrontendNG::OnHide()
438 {
439     foregroundFrontend_ = false;
440     CHECK_NULL_VOID(delegate_);
441     delegate_->OnPageHide();
442 }
443 
CallRouterBack()444 void DeclarativeFrontendNG::CallRouterBack()
445 {
446     if (delegate_) {
447         if (delegate_->GetStackSize() == 1 && isSubWindow_) {
448             LOGW("Can't back because this is the last page of sub window!");
449             return;
450         }
451         delegate_->Back("", "");
452     }
453 }
454 
OnSurfaceChanged(int32_t width,int32_t height)455 void DeclarativeFrontendNG::OnSurfaceChanged(int32_t width, int32_t height)
456 {
457     // TODO: update media query infos
458     if (delegate_) {
459         delegate_->OnSurfaceChanged();
460     }
461 }
462 
OnLayoutCompleted(const std::string & componentId)463 void DeclarativeFrontendNG::OnLayoutCompleted(const std::string& componentId)
464 {
465     if (delegate_) {
466         delegate_->OnLayoutCompleted(componentId);
467     }
468 }
469 
OnDrawCompleted(const std::string & componentId)470 void DeclarativeFrontendNG::OnDrawCompleted(const std::string& componentId)
471 {
472     if (delegate_) {
473         delegate_->OnDrawCompleted(componentId);
474     }
475 }
476 
DumpFrontend() const477 void DeclarativeFrontendNG::DumpFrontend() const
478 {
479     if (!delegate_) {
480         return;
481     }
482     int32_t routerIndex = 0;
483     std::string routerName;
484     std::string routerPath;
485     delegate_->GetState(routerIndex, routerName, routerPath);
486 
487     if (DumpLog::GetInstance().GetDumpFile()) {
488         DumpLog::GetInstance().AddDesc("Components: " + std::to_string(delegate_->GetComponentsCount()));
489         DumpLog::GetInstance().AddDesc("Path: " + routerPath);
490         DumpLog::GetInstance().AddDesc("Length: " + std::to_string(routerIndex));
491         DumpLog::GetInstance().Print(0, routerName, 0);
492     }
493 }
494 
GetPagePath() const495 std::string DeclarativeFrontendNG::GetPagePath() const
496 {
497     if (!delegate_) {
498         return "";
499     }
500     int32_t routerIndex = 0;
501     std::string routerName;
502     std::string routerPath;
503     delegate_->GetState(routerIndex, routerName, routerPath);
504     return routerPath + routerName;
505 }
506 
TriggerGarbageCollection()507 void DeclarativeFrontendNG::TriggerGarbageCollection()
508 {
509     if (jsEngine_) {
510         jsEngine_->RunGarbageCollection();
511     }
512 }
513 
DumpHeapSnapshot(bool isPrivate)514 void DeclarativeFrontendNG::DumpHeapSnapshot(bool isPrivate)
515 {
516     if (jsEngine_) {
517         jsEngine_->DumpHeapSnapshot(isPrivate);
518     }
519 }
520 
RestoreRouterStack(const std::string & contentInfo)521 std::string DeclarativeFrontendNG::RestoreRouterStack(const std::string& contentInfo)
522 {
523     if (delegate_) {
524         return delegate_->RestoreRouterStack(contentInfo);
525     }
526     return "";
527 }
528 
GetContentInfo() const529 std::string DeclarativeFrontendNG::GetContentInfo() const
530 {
531     if (delegate_) {
532         return delegate_->GetContentInfo();
533     }
534     return "";
535 }
536 
SetColorMode(ColorMode colorMode)537 void DeclarativeFrontendNG::SetColorMode(ColorMode colorMode)
538 {
539     // TODO: update media query infos
540     if (delegate_) {
541         delegate_->SetColorMode(colorMode);
542     }
543 }
544 
RebuildAllPages()545 void DeclarativeFrontendNG::RebuildAllPages()
546 {
547     LOGW("RebuildAllPages not implemented");
548     if (delegate_) {
549         delegate_->RebuildAllPages();
550     }
551 }
552 
FlushReload()553 void DeclarativeFrontendNG::FlushReload()
554 {
555     if (jsEngine_) {
556         jsEngine_->FlushReload();
557     }
558 }
559 
HotReload()560 void DeclarativeFrontendNG::HotReload()
561 {
562     auto manager = GetPageRouterManager();
563     CHECK_NULL_VOID(manager);
564     manager->FlushFrontend();
565 }
566 } // namespace OHOS::Ace
567