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/card_frontend/card_frontend_declarative.h"
17
18 #include <memory>
19 #include <vector>
20
21 #include "base/log/event_report.h"
22 #include "base/log/log_wrapper.h"
23 #include "base/utils/utils.h"
24 #include "core/common/thread_checker.h"
25 #include "frameworks/bridge/common/utils/utils.h"
26 #include "frameworks/bridge/declarative_frontend/ng/page_router_manager_factory.h"
27 #include "frameworks/core/pipeline_ng/pipeline_context.h"
28
29 namespace OHOS::Ace {
30 namespace {
31
32 const char FILE_TYPE_BIN[] = ".abc";
33
34 } // namespace
35
~CardFrontendDeclarative()36 CardFrontendDeclarative::~CardFrontendDeclarative()
37 {
38 LOG_DESTROY();
39 }
40
Initialize(FrontendType type,const RefPtr<TaskExecutor> & taskExecutor)41 bool CardFrontendDeclarative::Initialize(FrontendType type, const RefPtr<TaskExecutor>& taskExecutor)
42 {
43 type_ = type;
44 taskExecutor_ = taskExecutor;
45 InitializeDelegate(taskExecutor);
46 manifestParser_ = AceType::MakeRefPtr<Framework::ManifestParser>();
47 return true;
48 }
49
InitializeDelegate(const RefPtr<TaskExecutor> & taskExecutor)50 void CardFrontendDeclarative::InitializeDelegate(const RefPtr<TaskExecutor>& taskExecutor)
51 {
52 auto pageRouterManager = NG::PageRouterManagerFactory::CreateManager();
53 delegate_ = AceType::MakeRefPtr<Framework::CardFrontendDelegateDeclarative>(taskExecutor);
54 delegate_->SetPageRouterManager(pageRouterManager);
55 }
56
GetPageRouterManager() const57 RefPtr<NG::PageRouterManager> CardFrontendDeclarative::GetPageRouterManager() const
58 {
59 CHECK_NULL_RETURN(delegate_, nullptr);
60 return delegate_->GetPageRouterManager();
61 }
62
Destroy()63 void CardFrontendDeclarative::Destroy()
64 {
65 CHECK_RUN_ON(JS);
66 delegate_.Reset();
67 eventHandler_.Reset();
68 }
69
AttachPipelineContext(const RefPtr<PipelineBase> & context)70 void CardFrontendDeclarative::AttachPipelineContext(const RefPtr<PipelineBase>& context)
71 {
72 auto pipelineContext = DynamicCast<NG::PipelineContext>(context);
73 CHECK_NULL_VOID(delegate_);
74 CHECK_NULL_VOID(pipelineContext);
75 eventHandler_ = AceType::MakeRefPtr<CardEventHandlerDeclarative>(delegate_);
76
77 holder_.Attach(context);
78 delegate_->AttachPipelineContext(context);
79 }
80
SetAssetManager(const RefPtr<AssetManager> & assetManager)81 void CardFrontendDeclarative::SetAssetManager(const RefPtr<AssetManager>& assetManager)
82 {
83 assetManager_ = assetManager;
84 if (delegate_) {
85 delegate_->SetAssetManager(assetManager);
86 }
87 }
88
RunPage(const std::string & url,const std::string & params)89 UIContentErrorCode CardFrontendDeclarative::RunPage(const std::string& url, const std::string& params)
90 {
91 std::string urlPath;
92 if (GetFormSrc().empty()) {
93 ParseManifest();
94 if (!url.empty()) {
95 urlPath = manifestParser_->GetRouter()->GetPagePath(url, FILE_TYPE_BIN);
96 }
97 if (urlPath.empty()) {
98 urlPath = manifestParser_->GetRouter()->GetEntry(FILE_TYPE_BIN);
99 }
100 } else {
101 urlPath = GetFormSrcPath(GetFormSrc(), FILE_TYPE_BIN);
102 }
103 if (urlPath.empty()) {
104 return UIContentErrorCode::NULL_URL;
105 }
106
107 if (delegate_) {
108 auto container = Container::Current();
109 if (!container) {
110 return UIContentErrorCode::NULL_POINTER;
111 }
112 container->SetCardFrontend(AceType::WeakClaim(this), cardId_);
113 return delegate_->RunCard(urlPath, params, "", cardId_);
114 }
115
116 return UIContentErrorCode::NULL_POINTER;
117 }
118
OnPageLoaded(const RefPtr<Framework::JsAcePage> & page)119 void CardFrontendDeclarative::OnPageLoaded(const RefPtr<Framework::JsAcePage>& page)
120 {
121 CHECK_RUN_ON(JS);
122 // Pop all JS command and execute them in UI thread.
123 auto jsCommands = std::make_shared<std::vector<RefPtr<Framework::JsCommand>>>();
124 page->PopAllCommands(*jsCommands);
125 page->SetPipelineContext(holder_.Get());
126 taskExecutor_->PostTask(
127 [weak = AceType::WeakClaim(this), page, jsCommands] {
128 auto frontend = weak.Upgrade();
129 CHECK_NULL_VOID(frontend);
130 // Flush all JS commands.
131 for (const auto& command : *jsCommands) {
132 command->Execute(page);
133 }
134
135 auto pipelineContext = AceType::DynamicCast<PipelineContext>(frontend->holder_.Get());
136 CHECK_NULL_VOID(pipelineContext);
137 auto minSdk = frontend->manifestParser_->GetMinPlatformVersion();
138 pipelineContext->SetMinPlatformVersion(minSdk);
139
140 auto document = page->GetDomDocument();
141 if (frontend->pageLoaded_) {
142 page->ClearShowCommand();
143 std::vector<NodeId> dirtyNodes;
144 page->PopAllDirtyNodes(dirtyNodes);
145 if (dirtyNodes.empty()) {
146 return;
147 }
148 auto rootNodeId = dirtyNodes.front();
149 if (rootNodeId == DOM_ROOT_NODE_ID_BASE) {
150 auto patchComponent = page->BuildPagePatch(rootNodeId);
151 if (patchComponent) {
152 pipelineContext->ScheduleUpdate(patchComponent);
153 }
154 }
155 if (document) {
156 // When a component is configured with "position: fixed", there is a proxy node in root tree
157 // instead of the real composed node. So here updates the real composed node.
158 for (int32_t nodeId : document->GetProxyRelatedNodes()) {
159 auto patchComponent = page->BuildPagePatch(nodeId);
160 if (patchComponent) {
161 pipelineContext->ScheduleUpdate(patchComponent);
162 }
163 }
164 }
165 return;
166 }
167
168 // Just clear all dirty nodes.
169 page->ClearAllDirtyNodes();
170 if (document) {
171 document->HandleComponentPostBinding();
172 }
173 if (pipelineContext->GetAccessibilityManager()) {
174 pipelineContext->GetAccessibilityManager()->HandleComponentPostBinding();
175 }
176 if (pipelineContext->CanPushPage()) {
177 pipelineContext->PushPage(page->BuildPage(page->GetUrl()));
178 frontend->pageLoaded_ = true;
179 }
180 },
181 TaskExecutor::TaskType::UI, "ArkUICardFrontendPageLoaded");
182 }
183
UpdateData(const std::string & dataList)184 void CardFrontendDeclarative::UpdateData(const std::string& dataList)
185 {
186 taskExecutor_->PostTask(
187 [weak = AceType::WeakClaim(this), dataList] {
188 auto frontend = weak.Upgrade();
189 if (frontend) {
190 frontend->UpdatePageData(dataList);
191 }
192 },
193 TaskExecutor::TaskType::UI, "ArkUICardFrontendUpdatePageData"); // eTSCard UI == Main JS/UI/PLATFORM
194 }
195
UpdatePageData(const std::string & dataList)196 void CardFrontendDeclarative::UpdatePageData(const std::string& dataList)
197 {
198 CHECK_RUN_ON(UI); // eTSCard UI == Main JS/UI/PLATFORM
199 if (!delegate_) {
200 return;
201 }
202 delegate_->UpdatePageData(dataList);
203 }
204
SetColorMode(ColorMode colorMode)205 void CardFrontendDeclarative::SetColorMode(ColorMode colorMode)
206 {
207 taskExecutor_->PostTask(
208 [weak = AceType::WeakClaim(this), colorMode]() {
209 auto frontend = weak.Upgrade();
210 if (frontend) {
211 frontend->colorMode_ = colorMode;
212 if (!frontend->delegate_) {
213 return;
214 }
215 frontend->OnMediaFeatureUpdate();
216 }
217 },
218 TaskExecutor::TaskType::JS, "ArkUICardFrontendSetColorMode");
219 }
220
RebuildAllPages()221 void CardFrontendDeclarative::RebuildAllPages()
222 {
223 }
224
OnSurfaceChanged(int32_t width,int32_t height)225 void CardFrontendDeclarative::OnSurfaceChanged(int32_t width, int32_t height)
226 {
227 taskExecutor_->PostTask(
228 [weak = AceType::WeakClaim(this), width, height] {
229 auto frontend = weak.Upgrade();
230 if (frontend) {
231 frontend->HandleSurfaceChanged(width, height);
232 }
233 },
234 TaskExecutor::TaskType::JS, "ArkUICardFrontendSurfaceChanged");
235 }
236
HandleSurfaceChanged(int32_t width,int32_t height)237 void CardFrontendDeclarative::HandleSurfaceChanged(int32_t width, int32_t height)
238 {
239 CHECK_RUN_ON(JS);
240 OnMediaFeatureUpdate();
241 }
242
OnMediaFeatureUpdate()243 void CardFrontendDeclarative::OnMediaFeatureUpdate()
244 {
245 CHECK_RUN_ON(JS);
246 }
247
248 } // namespace OHOS::Ace
249