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 <cinttypes>
19 #include <utility>
20
21 #include "base/log/ace_trace.h"
22 #include "bridge/cj_frontend/runtime/cj_runtime_delegate.h"
23 #include "core/components_ng/base/view_partial_update_model.h"
24 #include "core/components_ng/base/view_stack_model.h"
25 #include "core/components_ng/pattern/custom/custom_measure_layout_node.h"
26
27 namespace OHOS::Ace::Framework {
28
GetProcessViewId(int64_t id)29 std::string GetProcessViewId(int64_t id)
30 {
31 return ViewStackModel::GetInstance()->ProcessViewId(std::to_string(id));
32 }
33
NativeView(sptr<RemoteView> cjView)34 NativeView::NativeView(sptr<RemoteView> cjView) : cjView_(std::move(cjView))
35 {
36 LOGD("Native View constructed: %{public}" PRId64 ".", GetID());
37 useNewPipeline_ = Container::IsCurrentUseNewPipeline();
38 instanceId_ = Container::CurrentId();
39 }
40
~NativeView()41 NativeView::~NativeView()
42 {
43 LOGD("Native View Destroyed: %{public}" PRId64 ".", GetID());
44 };
45
GetDeletedElemtIds(std::vector<int64_t> & vec)46 void NativeView::GetDeletedElemtIds(std::vector<int64_t>& vec)
47 {
48 LOGD("NativeView, getting elmtIds of all deleted Elements from ElementRegister:");
49 }
50
DeletedElmtIdsHaveBeenPurged(std::vector<int64_t> & vec)51 void NativeView::DeletedElmtIdsHaveBeenPurged(std::vector<int64_t>& vec)
52 {
53 LOGD("NativeView, getting elmtIds of all deleted Elements from ElementRegister:");
54 }
55
CreateUI()56 RefPtr<AceType> NativeView::CreateUI()
57 {
58 wptr<NativeView> weakThis = this;
59 NodeInfoPU partialUpdateCallbacks {
60 .appearFunc = [weakThis]() -> void {
61 auto self = weakThis.promote();
62 CHECK_NULL_VOID(self);
63 ContainerScope scope(self->instanceId_);
64 self->cjView_->OnAppear();
65 },
66 .renderFunc = [weakThis]() -> RefPtr<AceType> {
67 auto self = weakThis.promote();
68 CHECK_NULL_RETURN(self, nullptr);
69 ContainerScope scope(self->instanceId_);
70 if (!self->isFirstRender_) {
71 LOGW("the view has already called initial render");
72 return nullptr;
73 }
74 self->isFirstRender_ = false;
75 return self->InitialUIRender();
76 },
77 .updateFunc = [weakThis]() -> void {
78 auto self = weakThis.promote();
79 CHECK_NULL_VOID(self);
80 ContainerScope scope(self->instanceId_);
81 if (!self->needsUpdate_) {
82 LOGW("the view does not need to update");
83 return;
84 }
85 self->needsUpdate_ = false;
86 self->cjView_->Rerender();
87 for (const UpdateTask& updateTask : self->pendingUpdateTasks_) {
88 ViewPartialUpdateModel::GetInstance()->FlushUpdateTask(updateTask);
89 }
90 self->pendingUpdateTasks_.clear();
91 },
92 .removeFunc = [weakThis]() {
93 auto self = weakThis.promote();
94 CHECK_NULL_VOID(self);
95 self->Destroy();
96 },
97 .reloadFunc = [weakThis](bool deep) {
98 auto self = weakThis.promote();
99 CHECK_NULL_VOID(self);
100 ContainerScope scope(self->instanceId_);
101 self->cjView_->Reload(deep);
102 },
103 .completeReloadFunc = [weakThis]() -> RefPtr<AceType> {
104 auto view = weakThis.promote();
105 CHECK_NULL_RETURN(view, nullptr);
106 ContainerScope scope(view->instanceId_);
107 return view->InitialUIRender();
108 },
109 };
110 auto node = ViewPartialUpdateModel::GetInstance()->CreateNode(std::move(partialUpdateCallbacks));
111
112 node_ = node;
113
114 return node;
115 }
116
InitialUIRender()117 RefPtr<AceType> NativeView::InitialUIRender()
118 {
119 needsUpdate_ = false;
120 {
121 cjView_->OnAboutToRender();
122 }
123 {
124 cjView_->Render();
125 }
126 {
127 cjView_->OnAfterRender();
128 if (onRenderDone_) {
129 onRenderDone_();
130 }
131 }
132 return ViewStackModel::GetInstance()->Finish();
133 }
134
SyncInstanceId()135 void NativeView::SyncInstanceId()
136 {
137 restoreInstanceId_ = Container::CurrentId();
138 ContainerScope::UpdateCurrent(instanceId_);
139 }
140
RestoreInstanceId()141 void NativeView::RestoreInstanceId()
142 {
143 ContainerScope::UpdateCurrent(restoreInstanceId_);
144 }
145
146 /**
147 * marks the NativeView's composed component as needing update / rerender
148 */
MarkNeedUpdate()149 void NativeView::MarkNeedUpdate()
150 {
151 needsUpdate_ = ViewPartialUpdateModel::GetInstance()->MarkNeedUpdate(node_);
152 }
153
FlushReload()154 void NativeView::FlushReload()
155 {
156 auto node = node_.Upgrade();
157 if (!node) {
158 LOGE("fail to update due to custom Node is null");
159 return;
160 }
161 if (AceType::InstanceOf<NG::CustomNode>(node)) {
162 auto customNode = AceType::DynamicCast<NG::CustomNode>(node);
163 customNode->FlushReload();
164 }
165 }
166
FinishUpdateFunc(int32_t elmtId)167 void NativeView::FinishUpdateFunc(int32_t elmtId)
168 {
169 wptr<NativeView> weakThis = this;
170 ViewPartialUpdateModel::GetInstance()->FinishUpdate(node_, elmtId, [weakThis](const UpdateTask& task) {
171 auto cjView = weakThis.promote();
172 if (cjView) {
173 cjView->pendingUpdateTasks_.push_back(task);
174 }
175 });
176 }
177
Destroy()178 void NativeView::Destroy()
179 {
180 if (!cjView_) {
181 LOGE("NativeView::Destroy error, nativeId: %{public}" PRId64 " cj view not exist.", GetID());
182 return;
183 }
184 LOGD("NativeView::Destroy start, nativeId: %{public}" PRId64 ", cjId: %{public}" PRId64, GetID(), cjView_->GetID());
185 {
186 cjView_->OnDisappear();
187 }
188 {
189 cjView_->OnAboutToBeDeleted();
190 }
191 pendingUpdateTasks_.clear();
192 LOGD("NativeView::Destroy end");
193 }
194
Create(const sptr<NativeView> & view)195 void NativeView::Create(const sptr<NativeView>& view)
196 {
197 ViewStackModel::GetInstance()->Push(view->CreateUI(), true);
198 }
199
CleanUpAbandonedChild()200 void NativeView::CleanUpAbandonedChild()
201 {
202 LOGD("NativeView::CleanUpAbandonedChild");
203 }
204
FireOnShow()205 void NativeView::FireOnShow()
206 {
207 if (!cjView_) {
208 LOGE("NativeView::FireOnShow fail, no cj view on %{public}" PRId64 ".", GetID());
209 return;
210 }
211 {
212 cjView_->OnShow();
213 }
214 }
215
FireOnHide()216 void NativeView::FireOnHide()
217 {
218 if (!cjView_) {
219 LOGE("NativeView::FireOnHide fail, no cj view on %{public}" PRId64 ".", GetID());
220 return;
221 }
222 {
223 cjView_->OnHide();
224 }
225 }
226
FireOnBackPress()227 bool NativeView::FireOnBackPress()
228 {
229 if (!cjView_) {
230 LOGE("NativeView::FireOnBackPress fail, no cj view on %{public}" PRId64 ".", GetID());
231 return false;
232 }
233 {
234 return cjView_->OnBackPress();
235 }
236 }
237
FireOnTransition()238 void NativeView::FireOnTransition()
239 {
240 if (!cjView_) {
241 LOGE("NativeView::FireOnTransition fail, no cj view on %{public}" PRId64 ".", GetID());
242 return;
243 }
244 cjView_->OnTransition();
245 }
246
ExecuteUpdateWithValueParams(const std::string & jsonData)247 void NativeView::ExecuteUpdateWithValueParams(const std::string& jsonData)
248 {
249 if (!cjView_) {
250 LOGE("NativeView::ExecuteUpdateWithValueParams fail, no cj view on %{public}" PRId64 ".", GetID());
251 return;
252 }
253 cjView_->UpdateWithJson(jsonData);
254 }
255
Reload(bool deep)256 void RemoteView::Reload(bool deep)
257 {
258 auto forceCompleteRerenderFunc =
259 CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewForceCompleteRerender;
260 if (!forceCompleteRerenderFunc) {
261 LOGE("CJFunc: RemoteView::ForceCompleteRerender is empty.");
262 return;
263 }
264 forceCompleteRerenderFunc(GetID(), deep);
265 }
266
VoidCallback(void (* cjFunc)(int64_t),const char * funcName)267 void RemoteView::VoidCallback(void (*cjFunc)(int64_t), const char* funcName)
268 {
269 if (!cjFunc) {
270 LOGE("CJFunc: RemoteView::%{public}s is empty.", funcName);
271 return;
272 }
273 cjFunc(GetID());
274 }
275
Render()276 void RemoteView::Render()
277 {
278 VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewRender, "Render");
279 }
280
Rerender()281 void RemoteView::Rerender()
282 {
283 VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewRerender, "Rerender");
284 }
285
OnShow()286 void RemoteView::OnShow()
287 {
288 VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnShow, "OnShow");
289 }
290
OnHide()291 void RemoteView::OnHide()
292 {
293 VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnHide, "OnHide");
294 }
295
OnBackPress()296 bool RemoteView::OnBackPress()
297 {
298 auto onBackPressFunc = CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnBackPress;
299 if (!onBackPressFunc) {
300 LOGE("CJFunc: RemoteView::OnBackPress is empty.");
301 return false;
302 }
303 return onBackPressFunc(GetID());
304 }
305
UpdateWithJson(const std::string & value)306 void RemoteView::UpdateWithJson(const std::string& value)
307 {
308 auto updateWithJsonFunc =
309 CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewUpdateWithJson;
310 if (!updateWithJsonFunc) {
311 LOGE("CJFunc: RemoteView::UpdateWithJson is empty.");
312 return;
313 }
314 updateWithJsonFunc(GetID(), value.c_str());
315 }
316
OnAppear()317 void RemoteView::OnAppear()
318 {
319 VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAppear, "OnAppear");
320 }
321
OnTransition()322 void RemoteView::OnTransition()
323 {
324 VoidCallback(
325 CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnTransition, "OnTransition");
326 }
327
OnAboutToRender()328 void RemoteView::OnAboutToRender()
329 {
330 VoidCallback(
331 CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAboutToRender, "OnAboutToRender");
332 }
333
OnAboutToBeDeleted()334 void RemoteView::OnAboutToBeDeleted()
335 {
336 VoidCallback(CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAboutToBeDeleted,
337 "OnAboutToBeDeleted");
338 }
339
OnAfterRender()340 void RemoteView::OnAfterRender()
341 {
342 VoidCallback(
343 CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnAfterRender, "OnAfterRender");
344 }
345
OnDisappear()346 void RemoteView::OnDisappear()
347 {
348 VoidCallback(
349 CJRuntimeDelegate::GetInstance()->GetCJFuncs().atCOHOSAceFrameworkRemoteViewOnDisappear, "OnDisappear");
350 }
351
352 } // namespace OHOS::Ace::Framework
353