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 ACE_DCHECK(type_ == FrontendType::DECLARATIVE_JS);
45 InitializeDelegate(taskExecutor);
46 bool needPostJsTask = true;
47 auto container = Container::Current();
48 if (container) {
49 const auto& setting = container->GetSettings();
50 needPostJsTask = !(setting.usePlatformAsUIThread && setting.useUIAsJSThread);
51 }
52 auto initJSEngineTask = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_), delegate = delegate_] {
53 auto jsEngine = weakEngine.Upgrade();
54 if (!jsEngine) {
55 return;
56 }
57 jsEngine->Initialize(delegate);
58 };
59 if (needPostJsTask) {
60 taskExecutor->PostTask(initJSEngineTask, TaskExecutor::TaskType::JS);
61 } else {
62 initJSEngineTask();
63 }
64 taskExecutor_ = taskExecutor;
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 }
81
SetAssetManager(const RefPtr<AssetManager> & assetManager)82 void DeclarativeFrontendNG::SetAssetManager(const RefPtr<AssetManager>& assetManager)
83 {
84 LOGI("DeclarativeFrontendNG SetAssetManager.");
85 if (delegate_) {
86 delegate_->SetAssetManager(assetManager);
87 }
88 }
89
InitializeDelegate(const RefPtr<TaskExecutor> & taskExecutor)90 void DeclarativeFrontendNG::InitializeDelegate(const RefPtr<TaskExecutor>& taskExecutor)
91 {
92 auto pageRouterManager = AceType::MakeRefPtr<NG::PageRouterManager>();
93 auto loadPageCallback = [weakEngine = WeakPtr<Framework::JsEngine>(jsEngine_)](const std::string& url,
94 const std::function<void(const std::string&, int32_t)>& errorCallback) {
95 auto jsEngine = weakEngine.Upgrade();
96 if (!jsEngine) {
97 return false;
98 }
99 return jsEngine->LoadPageSource(url, errorCallback);
100 };
101 pageRouterManager->SetLoadJsCallback(std::move(loadPageCallback));
102
103 delegate_ = AceType::MakeRefPtr<Framework::FrontendDelegateDeclarativeNG>(taskExecutor);
104 delegate_->SetPageRouterManager(pageRouterManager);
105 if (jsEngine_) {
106 delegate_->SetGroupJsBridge(jsEngine_->GetGroupJsBridge());
107 }
108 }
109
GetPageRouterManager() const110 RefPtr<NG::PageRouterManager> DeclarativeFrontendNG::GetPageRouterManager() const
111 {
112 CHECK_NULL_RETURN(delegate_, nullptr);
113 return delegate_->GetPageRouterManager();
114 }
115
RunPage(int32_t pageId,const std::string & url,const std::string & params)116 void DeclarativeFrontendNG::RunPage(int32_t pageId, const std::string& url, const std::string& params)
117 {
118 auto container = Container::Current();
119 auto isStageModel = container ? container->IsUseStageModel() : false;
120 if (!isStageModel) {
121 // In NG structure and fa mode, first load app.js
122 auto taskExecutor = container ? container->GetTaskExecutor() : nullptr;
123 CHECK_NULL_VOID(taskExecutor);
124 taskExecutor->PostTask(
125 [weak = AceType::WeakClaim(this)]() {
126 auto frontend = weak.Upgrade();
127 CHECK_NULL_VOID(frontend);
128 CHECK_NULL_VOID(frontend->jsEngine_);
129 frontend->jsEngine_->LoadFaAppSource();
130 },
131 TaskExecutor::TaskType::JS);
132 }
133 // Not use this pageId from backend, manage it in FrontendDelegateDeclarative.
134 if (delegate_) {
135 delegate_->RunPage(url, params, pageProfile_);
136 }
137 }
138
ReplacePage(const std::string & url,const std::string & params)139 void DeclarativeFrontendNG::ReplacePage(const std::string& url, const std::string& params)
140 {
141 if (delegate_) {
142 delegate_->Replace(url, params);
143 }
144 }
145
PushPage(const std::string & url,const std::string & params)146 void DeclarativeFrontendNG::PushPage(const std::string& url, const std::string& params)
147 {
148 if (delegate_) {
149 delegate_->Push(url, params);
150 }
151 }
152
NavigatePage(uint8_t type,const PageTarget & target,const std::string & params)153 void DeclarativeFrontendNG::NavigatePage(uint8_t type, const PageTarget& target, const std::string& params)
154 {
155 if (delegate_) {
156 delegate_->NavigatePage(type, target, params);
157 }
158 }
159
OnWindowDisplayModeChanged(bool isShownInMultiWindow,const std::string & data)160 void DeclarativeFrontendNG::OnWindowDisplayModeChanged(bool isShownInMultiWindow, const std::string& data)
161 {
162 LOGW("OnWindowDisplayModeChanged not implemented");
163 }
164
GetAccessibilityManager() const165 RefPtr<AccessibilityManager> DeclarativeFrontendNG::GetAccessibilityManager() const
166 {
167 return accessibilityManager_;
168 }
169
GetWindowConfig()170 WindowConfig& DeclarativeFrontendNG::GetWindowConfig()
171 {
172 if (!delegate_) {
173 static WindowConfig windowConfig;
174 LOGW("delegate is null, return default config");
175 return windowConfig;
176 }
177 return delegate_->GetWindowConfig();
178 }
179
OnBackPressed()180 bool DeclarativeFrontendNG::OnBackPressed()
181 {
182 CHECK_NULL_RETURN(delegate_, false);
183 return delegate_->OnPageBackPress();
184 }
185
OnShow()186 void DeclarativeFrontendNG::OnShow()
187 {
188 foregroundFrontend_ = true;
189 CHECK_NULL_VOID(delegate_);
190 delegate_->OnPageShow();
191 }
192
OnHide()193 void DeclarativeFrontendNG::OnHide()
194 {
195 foregroundFrontend_ = false;
196 CHECK_NULL_VOID(delegate_);
197 delegate_->OnPageHide();
198 }
199
CallRouterBack()200 void DeclarativeFrontendNG::CallRouterBack()
201 {
202 if (delegate_) {
203 if (delegate_->GetStackSize() == 1 && isSubWindow_) {
204 LOGW("Can't back because this is the last page of sub window!");
205 return;
206 }
207 delegate_->Back("", "");
208 }
209 }
210
OnSurfaceChanged(int32_t width,int32_t height)211 void DeclarativeFrontendNG::OnSurfaceChanged(int32_t width, int32_t height)
212 {
213 // TODO: update media query infos
214 }
215
DumpFrontend() const216 void DeclarativeFrontendNG::DumpFrontend() const {}
217
GetPagePath() const218 std::string DeclarativeFrontendNG::GetPagePath() const
219 {
220 if (!delegate_) {
221 return "";
222 }
223 int32_t routerIndex = 0;
224 std::string routerName;
225 std::string routerPath;
226 delegate_->GetState(routerIndex, routerName, routerPath);
227 return routerPath + routerName;
228 }
229
TriggerGarbageCollection()230 void DeclarativeFrontendNG::TriggerGarbageCollection()
231 {
232 if (jsEngine_) {
233 jsEngine_->RunGarbageCollection();
234 }
235 }
236
DumpHeapSnapshot(bool isPrivate)237 void DeclarativeFrontendNG::DumpHeapSnapshot(bool isPrivate)
238 {
239 if (jsEngine_) {
240 jsEngine_->DumpHeapSnapshot(isPrivate);
241 }
242 }
243
SetColorMode(ColorMode colorMode)244 void DeclarativeFrontendNG::SetColorMode(ColorMode colorMode)
245 {
246 // TODO: update media query infos
247 }
248
RebuildAllPages()249 void DeclarativeFrontendNG::RebuildAllPages()
250 {
251 LOGW("RebuildAllPages not implemented");
252 }
253
254 } // namespace OHOS::Ace
255