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