• 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/card_frontend/card_frontend_declarative.h"
17 
18 #include <memory>
19 #include <vector>
20 
21 #include "base/log/event_report.h"
22 #include "base/utils/utils.h"
23 #include "core/common/thread_checker.h"
24 #include "frameworks/bridge/common/utils/utils.h"
25 #include "frameworks/core/pipeline_ng/pipeline_context.h"
26 
27 namespace OHOS::Ace {
28 namespace {
29 
30 const char FILE_TYPE_BIN[] = ".abc";
31 
32 } // namespace
33 
~CardFrontendDeclarative()34 CardFrontendDeclarative::~CardFrontendDeclarative()
35 {
36     LOG_DESTROY();
37 }
38 
Initialize(FrontendType type,const RefPtr<TaskExecutor> & taskExecutor)39 bool CardFrontendDeclarative::Initialize(FrontendType type, const RefPtr<TaskExecutor>& taskExecutor)
40 {
41     type_ = type;
42     taskExecutor_ = taskExecutor;
43     InitializeDelegate(taskExecutor);
44     manifestParser_ = AceType::MakeRefPtr<Framework::ManifestParser>();
45     return true;
46 }
47 
InitializeDelegate(const RefPtr<TaskExecutor> & taskExecutor)48 void CardFrontendDeclarative::InitializeDelegate(const RefPtr<TaskExecutor>& taskExecutor)
49 {
50     auto pageRouterManager = AceType::MakeRefPtr<NG::PageRouterManager>();
51     delegate_ = AceType::MakeRefPtr<Framework::CardFrontendDelegateDeclarative>(taskExecutor);
52     delegate_->SetPageRouterManager(pageRouterManager);
53 }
54 
GetPageRouterManager() const55 RefPtr<NG::PageRouterManager> CardFrontendDeclarative::GetPageRouterManager() const
56 {
57     CHECK_NULL_RETURN(delegate_, nullptr);
58     return delegate_->GetPageRouterManager();
59 }
60 
Destroy()61 void CardFrontendDeclarative::Destroy()
62 {
63     CHECK_RUN_ON(JS);
64     delegate_.Reset();
65     eventHandler_.Reset();
66 }
67 
AttachPipelineContext(const RefPtr<PipelineBase> & context)68 void CardFrontendDeclarative::AttachPipelineContext(const RefPtr<PipelineBase>& context)
69 {
70     auto pipelineContext = DynamicCast<NG::PipelineContext>(context);
71     CHECK_NULL_VOID_NOLOG(delegate_);
72     CHECK_NULL_VOID_NOLOG(pipelineContext);
73     eventHandler_ = AceType::MakeRefPtr<CardEventHandlerDeclarative>(delegate_);
74 
75     holder_.Attach(context);
76     delegate_->AttachPipelineContext(context);
77 }
78 
SetAssetManager(const RefPtr<AssetManager> & assetManager)79 void CardFrontendDeclarative::SetAssetManager(const RefPtr<AssetManager>& assetManager)
80 {
81     assetManager_ = assetManager;
82     if (delegate_) {
83         delegate_->SetAssetManager(assetManager);
84     }
85 }
86 
RunPage(int32_t pageId,const std::string & url,const std::string & params)87 void CardFrontendDeclarative::RunPage(int32_t pageId, const std::string& url, const std::string& params)
88 {
89     std::string urlPath;
90     if (GetFormSrc().empty()) {
91         ParseManifest();
92         if (!url.empty()) {
93             urlPath = manifestParser_->GetRouter()->GetPagePath(url, FILE_TYPE_BIN);
94         }
95         if (urlPath.empty()) {
96             urlPath = manifestParser_->GetRouter()->GetEntry(FILE_TYPE_BIN);
97         }
98     } else {
99         urlPath = GetFormSrcPath(GetFormSrc(), FILE_TYPE_BIN);
100     }
101     if (urlPath.empty()) {
102         LOGE("fail to eTS Card run page due to path url is empty");
103         EventReport::SendFormException(FormExcepType::RUN_PAGE_ERR);
104         return;
105     }
106 
107     if (delegate_) {
108         auto container = Container::Current();
109         if (!container) {
110             LOGE("RunPage host container null");
111             EventReport::SendFormException(FormExcepType::RUN_PAGE_ERR);
112             return;
113         }
114         container->SetCardFrontend(AceType::WeakClaim(this), cardId_);
115         delegate_->RunCard(urlPath, params, "", cardId_);
116     }
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_NOLOG(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);
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); // 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         LOGE("the delegate is null");
201         EventReport::SendFormException(FormExcepType::UPDATE_PAGE_ERR);
202         return;
203     }
204     delegate_->UpdatePageData(dataList);
205 }
206 
SetColorMode(ColorMode colorMode)207 void CardFrontendDeclarative::SetColorMode(ColorMode colorMode)
208 {
209     taskExecutor_->PostTask(
210         [weak = AceType::WeakClaim(this), colorMode]() {
211             auto frontend = weak.Upgrade();
212             if (frontend) {
213                 frontend->colorMode_ = colorMode;
214                 if (!frontend->delegate_) {
215                     LOGE("the delegate is null");
216                     return;
217                 }
218                 frontend->OnMediaFeatureUpdate();
219             } else {
220                 LOGE("eTS Card frontend is nullptr");
221             }
222         },
223         TaskExecutor::TaskType::JS);
224 }
225 
RebuildAllPages()226 void CardFrontendDeclarative::RebuildAllPages()
227 {
228 }
229 
OnSurfaceChanged(int32_t width,int32_t height)230 void CardFrontendDeclarative::OnSurfaceChanged(int32_t width, int32_t height)
231 {
232     taskExecutor_->PostTask(
233         [weak = AceType::WeakClaim(this), width, height] {
234             auto frontend = weak.Upgrade();
235             if (frontend) {
236                 frontend->HandleSurfaceChanged(width, height);
237             }
238         },
239         TaskExecutor::TaskType::JS);
240 }
241 
HandleSurfaceChanged(int32_t width,int32_t height)242 void CardFrontendDeclarative::HandleSurfaceChanged(int32_t width, int32_t height)
243 {
244     CHECK_RUN_ON(JS);
245     OnMediaFeatureUpdate();
246 }
247 
OnMediaFeatureUpdate()248 void CardFrontendDeclarative::OnMediaFeatureUpdate()
249 {
250     CHECK_RUN_ON(JS);
251 }
252 
253 } // namespace OHOS::Ace
254