• 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         .renderFunc = [weakThis](int64_t deadline, bool& isTimeout) -> RefPtr<AceType> {
64             auto self = weakThis.promote();
65             CHECK_NULL_RETURN(self, nullptr);
66             ContainerScope scope(self->instanceId_);
67             if (!self->isFirstRender_) {
68                 LOGW("the view has already called initial render");
69                 return nullptr;
70             }
71             self->isFirstRender_ = false;
72             return self->InitialUIRender();
73         },
74         .updateFunc = [weakThis]() -> void {
75             auto self = weakThis.promote();
76             CHECK_NULL_VOID(self);
77             ContainerScope scope(self->instanceId_);
78             if (!self->needsUpdate_) {
79                 LOGW("the view does not need to update");
80                 return;
81             }
82             self->needsUpdate_ = false;
83             self->cjView_->Rerender();
84             for (const UpdateTask& updateTask : self->pendingUpdateTasks_) {
85                 ViewPartialUpdateModel::GetInstance()->FlushUpdateTask(updateTask);
86             }
87             self->pendingUpdateTasks_.clear();
88         },
89         .removeFunc = [weakThis]() {
90             auto self = weakThis.promote();
91             CHECK_NULL_VOID(self);
92             self->Destroy();
93         },
94         .reloadFunc = [weakThis](bool deep) {
95             auto self = weakThis.promote();
96             CHECK_NULL_VOID(self);
97             ContainerScope scope(self->instanceId_);
98             self->cjView_->Reload(deep);
99         },
100         .didBuildFunc =
101             [weakThis]() {
102                 auto self = weakThis.promote();
103                 CHECK_NULL_VOID(self);
104                 ContainerScope scope(self->instanceId_);
105                 self->cjView_->OnDidBuild();
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         .recycleFunc =
114             [weakThis]() {
115                 auto self = weakThis.promote();
116                 CHECK_NULL_VOID(self);
117                 ContainerScope scope(self->instanceId_);
118                 self->cjView_->AboutToRecycle();
119             },
120         .reuseFunc =
121             [weakThis](void* params) {
122                 auto self = weakThis.promote();
123                 CHECK_NULL_VOID(self);
124                 ContainerScope scope(self->instanceId_);
125                 // only support string yet in cj
126                 std::string* val = static_cast<std::string*>(params);
127                 CHECK_NULL_VOID(val);
128                 self->cjView_->AboutToReuse(*val);
129             },
130         .recycleCustomNodeFunc = [weakThis](const RefPtr<NG::CustomNodeBase>& recycleNode) -> void {
131             auto self = weakThis.promote();
132             CHECK_NULL_VOID(self);
133             ContainerScope scope(self->instanceId_);
134             auto name = self->GetRecycleCustomNodeName();
135             if (name.empty()) {
136                 return;
137             }
138             auto recycleUINode = AceType::DynamicCast<NG::UINode>(recycleNode);
139             recycleUINode->SetActive(false);
140             self->SetRecycleCustomNode(recycleNode);
141             self->cjView_->RecycleSelf(name);
142             if (!recycleNode->HasRecycleRenderFunc() && self->recycleCustomNode_) {
143                 recycleUINode->SetJSViewActive(false, false, true);
144                 self->cjView_->AboutToRecycle();
145             }
146             recycleNode->ResetRecycle();
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     auto* stack = NG::ViewStackProcessor::GetInstance();
256     auto dummyNode = NG::RecycleDummyNode::WrapRecycleDummyNode(node, stack->GetRecycleNodeId());
257     ViewStackModel::GetInstance()->Push(dummyNode, true);
258 }
259 
CleanUpAbandonedChild()260 void NativeView::CleanUpAbandonedChild()
261 {
262     LOGD("NativeView::CleanUpAbandonedChild");
263 }
264 
FireOnShow()265 void NativeView::FireOnShow()
266 {
267     if (!cjView_) {
268         LOGE("NativeView::FireOnShow fail, no cj view on %{public}" PRId64 ".", GetID());
269         return;
270     }
271     {
272         cjView_->OnShow();
273     }
274 }
275 
FireOnHide()276 void NativeView::FireOnHide()
277 {
278     if (!cjView_) {
279         LOGE("NativeView::FireOnHide fail, no cj view on %{public}" PRId64 ".", GetID());
280         return;
281     }
282     {
283         cjView_->OnHide();
284     }
285 }
286 
FireOnBackPress()287 bool NativeView::FireOnBackPress()
288 {
289     if (!cjView_) {
290         LOGE("NativeView::FireOnBackPress fail, no cj view on %{public}" PRId64 ".", GetID());
291         return false;
292     }
293     {
294         return cjView_->OnBackPress();
295     }
296 }
297 
FireOnTransition()298 void NativeView::FireOnTransition()
299 {
300     if (!cjView_) {
301         LOGE("NativeView::FireOnTransition fail, no cj view on %{public}" PRId64 ".", GetID());
302         return;
303     }
304     cjView_->OnTransition();
305 }
306 
ExecuteUpdateWithValueParams(const std::string & jsonData)307 void NativeView::ExecuteUpdateWithValueParams(const std::string& jsonData)
308 {
309     if (!cjView_) {
310         LOGE("NativeView::ExecuteUpdateWithValueParams fail, no cj view on %{public}" PRId64 ".", GetID());
311         return;
312     }
313     cjView_->UpdateWithJson(jsonData);
314 }
315 
Reload(bool deep)316 void RemoteView::Reload(bool deep)
317 {
318     auto forceCompleteRerenderFunc =
319         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewForceCompleteRerender;
320     if (!forceCompleteRerenderFunc) {
321         LOGE("CJFunc: RemoteView::ForceCompleteRerender is empty.");
322         return;
323     }
324     forceCompleteRerenderFunc(GetID(), deep);
325 }
326 
VoidCallback(void (* cjFunc)(int64_t),const char * funcName)327 void RemoteView::VoidCallback(void (*cjFunc)(int64_t), const char* funcName)
328 {
329     if (!cjFunc) {
330         LOGE("CJFunc: RemoteView::%{public}s is empty.", funcName);
331         return;
332     }
333     cjFunc(GetID());
334 }
335 
Render()336 void RemoteView::Render()
337 {
338     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewRender, "Render");
339 }
340 
Rerender()341 void RemoteView::Rerender()
342 {
343     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewRerender, "Rerender");
344 }
345 
OnShow()346 void RemoteView::OnShow()
347 {
348     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnShow, "OnShow");
349 }
350 
OnHide()351 void RemoteView::OnHide()
352 {
353     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnHide, "OnHide");
354 }
355 
OnBackPress()356 bool RemoteView::OnBackPress()
357 {
358     auto onBackPressFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnBackPress;
359     if (!onBackPressFunc) {
360         LOGE("CJFunc: RemoteView::OnBackPress is empty.");
361         return false;
362     }
363     return onBackPressFunc(GetID());
364 }
365 
UpdateWithJson(const std::string & value)366 void RemoteView::UpdateWithJson(const std::string& value)
367 {
368     auto updateWithJsonFunc =
369         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewUpdateWithJson;
370     if (!updateWithJsonFunc) {
371         LOGE("CJFunc: RemoteView::UpdateWithJson is empty.");
372         return;
373     }
374     updateWithJsonFunc(GetID(), value.c_str());
375 }
376 
OnAppear()377 void RemoteView::OnAppear()
378 {
379     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAppear, "OnAppear");
380 }
381 
OnTransition()382 void RemoteView::OnTransition()
383 {
384     VoidCallback(
385         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnTransition, "OnTransition");
386 }
387 
OnAboutToRender()388 void RemoteView::OnAboutToRender()
389 {
390     VoidCallback(
391         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAboutToRender, "OnAboutToRender");
392 }
393 
OnAboutToBeDeleted()394 void RemoteView::OnAboutToBeDeleted()
395 {
396     VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAboutToBeDeleted,
397         "OnAboutToBeDeleted");
398 }
399 
OnAfterRender()400 void RemoteView::OnAfterRender()
401 {
402     VoidCallback(
403         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAfterRender, "OnAfterRender");
404 }
405 
OnDisappear()406 void RemoteView::OnDisappear()
407 {
408     VoidCallback(
409         CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnDisappear, "OnDisappear");
410 }
411 
OnDidBuild()412 void RemoteView::OnDidBuild()
413 {
414     VoidCallback(
415         CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewOnDidBuild, "OnDidBuild");
416 }
417 
AboutToReuse(const std::string & value)418 void RemoteView::AboutToReuse(const std::string& value)
419 {
420     auto aboutToReuseFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewAboutToReuse;
421     if (!aboutToReuseFunc) {
422         LOGE("CJFunc: RemoteView::AboutToReuse is empty.");
423         return;
424     }
425     aboutToReuseFunc(GetID(), value.c_str());
426 }
427 
AboutToRecycle()428 void RemoteView::AboutToRecycle()
429 {
430     VoidCallback(
431         CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewAboutToRecycle, "AboutToRecycle");
432 }
433 
RecycleSelf(const std::string & value)434 void RemoteView::RecycleSelf(const std::string& value)
435 {
436     auto recycleSelfFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncsV2().atCOHOSAceFrameworkRemoteViewRecycleSelf;
437     if (!recycleSelfFunc) {
438         LOGE("CJFunc: RemoteView::RecycleSelf is empty.");
439         return;
440     }
441     recycleSelfFunc(GetID(), value.c_str());
442 }
443 } // namespace OHOS::Ace::Framework
444