• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "bridge/cj_frontend/cppview/native_view.h"
17 
18 #include "bridge/cj_frontend/runtime/cj_runtime_delegate.h"
19 #include "core/components_ng/base/view_partial_update_model.h"
20 #include "core/components_ng/base/view_stack_model.h"
21 #include "core/components_ng/pattern/custom/custom_measure_layout_node.h"
22 #include "core/components_ng/pattern/recycle_view/recycle_dummy_node.h"
23 
24 namespace OHOS::Ace::Framework {
25 
GetProcessViewId(int64_t id)26 std::string GetProcessViewId(int64_t id)
27 {
28     return ViewStackModel::GetInstance()->ProcessViewId(std::to_string(id));
29 }
30 
NativeView(sptr<RemoteView> cjView)31 NativeView::NativeView(sptr<RemoteView> cjView) : cjView_(std::move(cjView))
32 {
33     LOGD("Native View constructed: %{public}" PRId64 ".", GetID());
34     useNewPipeline_ = Container::IsCurrentUseNewPipeline();
35     instanceId_ = Container::CurrentId();
36 }
37 
~NativeView()38 NativeView::~NativeView()
39 {
40     LOGD("Native View Destroyed: %{public}" PRId64 ".", GetID());
41 };
42 
GetDeletedElemtIds(std::vector<int64_t> & vec)43 void NativeView::GetDeletedElemtIds(std::vector<int64_t>& vec)
44 {
45     LOGD("NativeView, getting elmtIds of all deleted Elements from ElementRegister:");
46 }
47 
DeletedElmtIdsHaveBeenPurged(std::vector<int64_t> & vec)48 void NativeView::DeletedElmtIdsHaveBeenPurged(std::vector<int64_t>& vec)
49 {
50     LOGD("NativeView, getting elmtIds of all deleted Elements from ElementRegister:");
51 }
52 
CreateUI()53 RefPtr<AceType> NativeView::CreateUI()
54 {
55     wptr<NativeView> weakThis = this;
56     NodeInfoPU partialUpdateCallbacks {
57         .appearFunc = [weakThis]() -> void {
58             auto self = weakThis.promote();
59             CHECK_NULL_VOID(self);
60             ContainerScope scope(self->instanceId_);
61             self->cjView_->OnAppear();
62         },
63         .didBuildFunc =
64             [weakThis]() {
65                 auto self = weakThis.promote();
66                 CHECK_NULL_VOID(self);
67                 ContainerScope scope(self->instanceId_);
68                 self->cjView_->OnDidBuild();
69             },
70         .renderFunc = [weakThis](int64_t deadline, bool& isTimeout) -> RefPtr<AceType> {
71             auto self = weakThis.promote();
72             CHECK_NULL_RETURN(self, nullptr);
73             ContainerScope scope(self->instanceId_);
74             if (!self->isFirstRender_) {
75                 LOGW("the view has already called initial render");
76                 return nullptr;
77             }
78             self->isFirstRender_ = false;
79             return self->InitialUIRender();
80         },
81         .updateFunc = [weakThis]() -> void {
82             auto self = weakThis.promote();
83             CHECK_NULL_VOID(self);
84             ContainerScope scope(self->instanceId_);
85             if (!self->needsUpdate_) {
86                 LOGW("the view does not need to update");
87                 return;
88             }
89             self->needsUpdate_ = false;
90             self->cjView_->Rerender();
91             for (const UpdateTask& updateTask : self->pendingUpdateTasks_) {
92                 ViewPartialUpdateModel::GetInstance()->FlushUpdateTask(updateTask);
93             }
94             self->pendingUpdateTasks_.clear();
95         },
96         .removeFunc = [weakThis]() {
97             auto self = weakThis.promote();
98             CHECK_NULL_VOID(self);
99             self->Destroy();
100         },
101         .reloadFunc = [weakThis](bool deep) {
102             auto self = weakThis.promote();
103             CHECK_NULL_VOID(self);
104             ContainerScope scope(self->instanceId_);
105             self->cjView_->Reload(deep);
106         },
107         .completeReloadFunc = [weakThis](int64_t deadline, bool& isTimeout) -> RefPtr<AceType> {
108             auto view = weakThis.promote();
109             CHECK_NULL_RETURN(view, nullptr);
110             ContainerScope scope(view->instanceId_);
111             return view->InitialUIRender();
112         },
113         .recycleCustomNodeFunc = [weakThis](const RefPtr<NG::CustomNodeBase>& recycleNode) -> void {
114             auto self = weakThis.promote();
115             CHECK_NULL_VOID(self);
116             ContainerScope scope(self->instanceId_);
117             auto name = self->GetRecycleCustomNodeName();
118             if (name.empty()) {
119                 return;
120             }
121             auto recycleUINode = AceType::DynamicCast<NG::UINode>(recycleNode);
122             recycleUINode->SetActive(false);
123             self->SetRecycleCustomNode(recycleNode);
124             self->cjView_->RecycleSelf(name);
125             if (!recycleNode->HasRecycleRenderFunc() && self->recycleCustomNode_) {
126                 recycleUINode->SetJSViewActive(false, false, true);
127                 self->cjView_->AboutToRecycle();
128             }
129             recycleNode->ResetRecycle();
130         },
131         .recycleFunc =
132             [weakThis]() {
133                 auto self = weakThis.promote();
134                 CHECK_NULL_VOID(self);
135                 ContainerScope scope(self->instanceId_);
136                 self->cjView_->AboutToRecycle();
137             },
138         .reuseFunc =
139             [weakThis](void* params) {
140                 auto self = weakThis.promote();
141                 CHECK_NULL_VOID(self);
142                 ContainerScope scope(self->instanceId_);
143                 // only support string yet in cj
144                 std::string* val = static_cast<std::string*>(params);
145                 CHECK_NULL_VOID(val);
146                 self->cjView_->AboutToReuse(*val);
147             },
148     };
149     auto node = ViewPartialUpdateModel::GetInstance()->CreateNode(std::move(partialUpdateCallbacks));
150     node_ = node;
151     return node;
152 }
153 
InitialUIRender()154 RefPtr<AceType> NativeView::InitialUIRender()
155 {
156     needsUpdate_ = false;
157     {
158         cjView_->OnAboutToRender();
159     }
160     {
161         cjView_->Render();
162     }
163     {
164         cjView_->OnAfterRender();
165         if (onRenderDone_) {
166             onRenderDone_();
167         }
168     }
169     return ViewStackModel::GetInstance()->Finish();
170 }
171 
SyncInstanceId()172 void NativeView::SyncInstanceId()
173 {
174     restoreInstanceId_ = Container::CurrentId();
175     ContainerScope::UpdateCurrent(instanceId_);
176 }
177 
RestoreInstanceId()178 void NativeView::RestoreInstanceId()
179 {
180     ContainerScope::UpdateCurrent(restoreInstanceId_);
181 }
182 
183 /**
184  * marks the NativeView's composed component as needing update / rerender
185  */
MarkNeedUpdate()186 void NativeView::MarkNeedUpdate()
187 {
188     needsUpdate_ = ViewPartialUpdateModel::GetInstance()->MarkNeedUpdate(node_);
189 }
190 
FlushReload()191 void NativeView::FlushReload()
192 {
193     auto node = node_.Upgrade();
194     if (!node) {
195         LOGE("fail to update due to custom Node is null");
196         return;
197     }
198     if (AceType::InstanceOf<NG::CustomNode>(node)) {
199         auto customNode = AceType::DynamicCast<NG::CustomNode>(node);
200         customNode->FlushReload();
201     }
202 }
203 
FinishUpdateFunc(int32_t elmtId)204 void NativeView::FinishUpdateFunc(int32_t elmtId)
205 {
206     wptr<NativeView> weakThis = this;
207     ViewPartialUpdateModel::GetInstance()->FinishUpdate(node_, elmtId, [weakThis](const UpdateTask& task) {
208         auto cjView = weakThis.promote();
209         if (cjView) {
210             cjView->pendingUpdateTasks_.push_back(task);
211         }
212     });
213 }
214 
Destroy()215 void NativeView::Destroy()
216 {
217     if (!cjView_) {
218         LOGE("NativeView::Destroy error, nativeId: %{public}" PRId64 " cj view not exist.", GetID());
219         return;
220     }
221     LOGD("NativeView::Destroy start, nativeId: %{public}" PRId64 ", cjId: %{public}" PRId64, GetID(), cjView_->GetID());
222     {
223         cjView_->OnDisappear();
224     }
225     {
226         cjView_->OnAboutToBeDeleted();
227     }
228     pendingUpdateTasks_.clear();
229     LOGD("NativeView::Destroy end");
230 }
231 
Create(const sptr<NativeView> & view)232 void NativeView::Create(const sptr<NativeView>& view)
233 {
234     ViewStackModel::GetInstance()->Push(view->CreateUI(), true);
235 }
236 
CreateRecycle(const sptr<NativeView> & view,bool isRecycling,const std::string & nodeName,std::function<void ()> callback)237 void NativeView::CreateRecycle(
238     const sptr<NativeView>& view, bool isRecycling, const std::string& nodeName, std::function<void()> callback)
239 {
240     auto recycleUpdateFunc = [cjView = view, func = std::move(callback)]() -> void {
241         CHECK_NULL_VOID(cjView);
242         cjView->SetIsRecycleRerender(true);
243         func();
244         cjView->SetIsRecycleRerender(false);
245     };
246     view->SetRecycleCustomNodeName(nodeName);
247     RefPtr<AceType> node;
248 
249     if (isRecycling) {
250         node = view->GetCachedRecycleNode();
251         AceType::DynamicCast<NG::CustomNodeBase>(node)->SetRecycleRenderFunc(std::move(recycleUpdateFunc));
252     } else {
253         node = view->CreateUI();
254     }
255 
256     auto customNodeBase = AceType::DynamicCast<NG::CustomNodeBase>(node);
257     if (customNodeBase) {
258         customNodeBase->SetReuseId(nodeName);
259     }
260     auto* stack = NG::ViewStackProcessor::GetInstance();
261     auto dummyNode = NG::RecycleDummyNode::WrapRecycleDummyNode(node, stack->GetRecycleNodeId());
262     ViewStackModel::GetInstance()->Push(dummyNode, true);
263 }
264 
CleanUpAbandonedChild()265 void NativeView::CleanUpAbandonedChild()
266 {
267     LOGD("NativeView::CleanUpAbandonedChild");
268 }
269 
FireOnShow()270 void NativeView::FireOnShow()
271 {
272     if (!cjView_) {
273         LOGE("NativeView::FireOnShow fail, no cj view on %{public}" PRId64 ".", GetID());
274         return;
275     }
276     {
277         cjView_->OnShow();
278     }
279 }
280 
FireOnHide()281 void NativeView::FireOnHide()
282 {
283     if (!cjView_) {
284         LOGE("NativeView::FireOnHide fail, no cj view on %{public}" PRId64 ".", GetID());
285         return;
286     }
287     {
288         cjView_->OnHide();
289     }
290 }
291 
FireOnBackPress()292 bool NativeView::FireOnBackPress()
293 {
294     if (!cjView_) {
295         LOGE("NativeView::FireOnBackPress fail, no cj view on %{public}" PRId64 ".", GetID());
296         return false;
297     }
298     {
299         return cjView_->OnBackPress();
300     }
301 }
302 
FireOnTransition()303 void NativeView::FireOnTransition()
304 {
305     if (!cjView_) {
306         LOGE("NativeView::FireOnTransition fail, no cj view on %{public}" PRId64 ".", GetID());
307         return;
308     }
309     cjView_->OnTransition();
310 }
311 
ExecuteUpdateWithValueParams(const std::string & jsonData)312 void NativeView::ExecuteUpdateWithValueParams(const std::string& jsonData)
313 {
314     if (!cjView_) {
315         LOGE("NativeView::ExecuteUpdateWithValueParams fail, no cj view on %{public}" PRId64 ".", GetID());
316         return;
317     }
318     cjView_->UpdateWithJson(jsonData);
319 }
320 
Reload(bool deep)321 void RemoteView::Reload(bool deep)
322 {
323     auto forceCompleteRerenderFunc =
324         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewForceCompleteRerender;
325     if (!forceCompleteRerenderFunc) {
326         LOGE("CJFunc: RemoteView::ForceCompleteRerender is empty.");
327         return;
328     }
329     forceCompleteRerenderFunc(GetID(), deep);
330 }
331 
VoidCallback(void (* cjFunc)(int64_t),const char * funcName)332 void RemoteView::VoidCallback(void (*cjFunc)(int64_t), const char* funcName)
333 {
334     if (!cjFunc) {
335         LOGE("CJFunc: RemoteView::%{public}s is empty.", funcName);
336         return;
337     }
338     cjFunc(GetID());
339 }
340 
Render()341 void RemoteView::Render()
342 {
343     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewRender, "Render");
344 }
345 
Rerender()346 void RemoteView::Rerender()
347 {
348     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewRerender, "Rerender");
349 }
350 
OnShow()351 void RemoteView::OnShow()
352 {
353     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnShow, "OnShow");
354 }
355 
OnHide()356 void RemoteView::OnHide()
357 {
358     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnHide, "OnHide");
359 }
360 
OnBackPress()361 bool RemoteView::OnBackPress()
362 {
363     auto onBackPressFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnBackPress;
364     if (!onBackPressFunc) {
365         LOGE("CJFunc: RemoteView::OnBackPress is empty.");
366         return false;
367     }
368     return onBackPressFunc(GetID());
369 }
370 
UpdateWithJson(const std::string & value)371 void RemoteView::UpdateWithJson(const std::string& value)
372 {
373     auto updateWithJsonFunc =
374         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewUpdateWithJson;
375     if (!updateWithJsonFunc) {
376         LOGE("CJFunc: RemoteView::UpdateWithJson is empty.");
377         return;
378     }
379     updateWithJsonFunc(GetID(), value.c_str());
380 }
381 
OnAppear()382 void RemoteView::OnAppear()
383 {
384     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAppear, "OnAppear");
385 }
386 
OnTransition()387 void RemoteView::OnTransition()
388 {
389     VoidCallback(
390         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnTransition, "OnTransition");
391 }
392 
OnAboutToRender()393 void RemoteView::OnAboutToRender()
394 {
395     VoidCallback(
396         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAboutToRender, "OnAboutToRender");
397 }
398 
OnAboutToBeDeleted()399 void RemoteView::OnAboutToBeDeleted()
400 {
401     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAboutToBeDeleted,
402         "OnAboutToBeDeleted");
403 }
404 
OnAfterRender()405 void RemoteView::OnAfterRender()
406 {
407     VoidCallback(
408         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAfterRender, "OnAfterRender");
409 }
410 
OnDisappear()411 void RemoteView::OnDisappear()
412 {
413     VoidCallback(
414         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnDisappear, "OnDisappear");
415 }
416 
OnDidBuild()417 void RemoteView::OnDidBuild()
418 {
419     VoidCallback(
420         CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewOnDidBuild, "OnDidBuild");
421 }
422 
AboutToReuse(const std::string & value)423 void RemoteView::AboutToReuse(const std::string& value)
424 {
425     auto aboutToReuseFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewAboutToReuse;
426     if (!aboutToReuseFunc) {
427         LOGE("CJFunc: RemoteView::AboutToReuse is empty.");
428         return;
429     }
430     aboutToReuseFunc(GetID(), value.c_str());
431 }
432 
AboutToRecycle()433 void RemoteView::AboutToRecycle()
434 {
435     VoidCallback(
436         CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewAboutToRecycle, "AboutToRecycle");
437 }
438 
RecycleSelf(const std::string & value)439 void RemoteView::RecycleSelf(const std::string& value)
440 {
441     auto recycleSelfFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewRecycleSelf;
442     if (!recycleSelfFunc) {
443         LOGE("CJFunc: RemoteView::RecycleSelf is empty.");
444         return;
445     }
446     recycleSelfFunc(GetID(), value.c_str());
447 }
448 } // namespace OHOS::Ace::Framework
449