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 #include "core/interfaces/native/node/custom_dialog_model.h"
16
17 #include "interfaces/native/node/dialog_model.h"
18
19 #include "base/error/error_code.h"
20 #include "core/components_ng/pattern/dialog/custom_dialog_controller_model_ng.h"
21
22 namespace OHOS::Ace::NG::CustomDialog {
23 namespace {
24 constexpr int32_t DEFAULT_DIALOG_ALIGNMENT = -1;
25 constexpr uint32_t DEFAULT_MASK_COLOR = 0x33000000;
26 constexpr uint32_t DEFAULT_DIALOG_BACKGROUND_COLOR = 0x00000000;
27 constexpr int32_t ARKUI_ALIGNMENT_TOP_START_INDEX = 0;
28 constexpr int32_t ARKUI_ALIGNMENT_TOP_INDEX = 1;
29 constexpr int32_t ARKUI_ALIGNMENT_TOP_END_INDEX = 2;
30 constexpr int32_t ARKUI_ALIGNMENT_START_INDEX = 3;
31 constexpr int32_t ARKUI_ALIGNMENT_CENTER_INDEX = 4;
32 constexpr int32_t ARKUI_ALIGNMENT_END_INDEX = 5;
33 constexpr int32_t ARKUI_ALIGNMENT_BOTTOM_START_INDEX = 6;
34 constexpr int32_t ARKUI_ALIGNMENT_BOTTOM_INDEX = 7;
35 constexpr int32_t ARKUI_ALIGNMENT_BOTTOM_END_INDEX = 8;
36 constexpr float DEFAULT_AVOID_DISTANCE = 16.0f;
37 constexpr int32_t ARKUI_LEVEL_MODE_DEFAULT_VALUE = 0;
38 constexpr int32_t ARKUI_DEFAULT_LEVEL_UNIQUEID = -1;
39 constexpr int32_t ARKUI_IMMERSIVE_MODE_DEFAULT_VALUE = 0;
40
41 } // namespace
42
CreateDialog()43 ArkUIDialogHandle CreateDialog()
44 {
45 return new _ArkUIDialog({ .dialogHandle = nullptr,
46 .contentHandle = nullptr,
47 .alignment = DEFAULT_DIALOG_ALIGNMENT,
48 .offsetX = 0.0f,
49 .offsetY = 0.0f,
50 .isModal = true,
51 .autoCancel = true,
52 .maskColor = DEFAULT_MASK_COLOR,
53 .maskRect = nullptr,
54 .backgroundColor = DEFAULT_DIALOG_BACKGROUND_COLOR,
55 .cornerRadiusRect = nullptr,
56 .gridCount = -1,
57 .enableCustomStyle = false,
58 .showInSubWindow = false,
59 .enableCustomAnimation = false,
60 .onWillDismissCall = nullptr,
61 .onWillDismissCallByNDK = nullptr,
62 .userData = nullptr,
63 .keyboardAvoidDistanceValue = std::optional<ArkUI_Float32>(),
64 .keyboardAvoidDistanceUnit = DimensionUnit::VP,
65 .levelMode = ARKUI_LEVEL_MODE_DEFAULT_VALUE,
66 .levelUniqueId = ARKUI_DEFAULT_LEVEL_UNIQUEID,
67 .immersiveMode = ARKUI_IMMERSIVE_MODE_DEFAULT_VALUE,
68 });
69 }
70
DisposeDialog(ArkUIDialogHandle controllerHandler)71 void DisposeDialog(ArkUIDialogHandle controllerHandler)
72 {
73 CHECK_NULL_VOID(controllerHandler);
74 auto* dialog = reinterpret_cast<FrameNode*>(controllerHandler->dialogHandle);
75 if (dialog) {
76 dialog->DecRefCount();
77 }
78 controllerHandler->dialogHandle = nullptr;
79 auto* content = reinterpret_cast<FrameNode*>(controllerHandler->contentHandle);
80 if (content) {
81 content->DecRefCount();
82 }
83 controllerHandler->contentHandle = nullptr;
84 auto* maskRect = controllerHandler->maskRect;
85 if (maskRect) {
86 delete maskRect;
87 }
88 auto* cornerRadiusRect = controllerHandler->cornerRadiusRect;
89 if (cornerRadiusRect) {
90 delete cornerRadiusRect;
91 }
92 controllerHandler->onWillDismissCall = nullptr;
93 controllerHandler->onWillDismissCallByNDK = nullptr;
94 controllerHandler->userData = nullptr;
95 delete controllerHandler;
96 }
97
GetDialogAlignment(int32_t alignment)98 DialogAlignment GetDialogAlignment(int32_t alignment)
99 {
100 switch (alignment) {
101 case ARKUI_ALIGNMENT_TOP_START_INDEX:
102 return DialogAlignment::TOP_START;
103 case ARKUI_ALIGNMENT_TOP_INDEX:
104 return DialogAlignment::TOP;
105 case ARKUI_ALIGNMENT_TOP_END_INDEX:
106 return DialogAlignment::TOP_END;
107 case ARKUI_ALIGNMENT_START_INDEX:
108 return DialogAlignment::CENTER_START;
109 case ARKUI_ALIGNMENT_CENTER_INDEX:
110 return DialogAlignment::CENTER;
111 case ARKUI_ALIGNMENT_END_INDEX:
112 return DialogAlignment::CENTER_END;
113 case ARKUI_ALIGNMENT_BOTTOM_START_INDEX:
114 return DialogAlignment::BOTTOM_START;
115 case ARKUI_ALIGNMENT_BOTTOM_INDEX:
116 return DialogAlignment::BOTTOM;
117 case ARKUI_ALIGNMENT_BOTTOM_END_INDEX:
118 return DialogAlignment::BOTTOM_END;
119 default:
120 break;
121 }
122 return DialogAlignment::DEFAULT;
123 }
124
ParseDialogMask(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)125 void ParseDialogMask(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
126 {
127 CHECK_NULL_VOID(controllerHandler);
128 dialogProperties.maskColor = Color(controllerHandler->maskColor);
129 if (!controllerHandler->maskRect) {
130 return;
131 }
132 DimensionRect maskRect;
133 maskRect.SetOffset(DimensionOffset(Dimension(controllerHandler->maskRect->x, DimensionUnit::VP),
134 Dimension(controllerHandler->maskRect->y, DimensionUnit::VP)));
135 maskRect.SetSize(DimensionSize(Dimension(controllerHandler->maskRect->width, DimensionUnit::VP),
136 Dimension(controllerHandler->maskRect->height, DimensionUnit::VP)));
137 dialogProperties.maskRect = maskRect;
138 }
139
ParseDialogCornerRadiusRect(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)140 void ParseDialogCornerRadiusRect(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
141 {
142 CHECK_NULL_VOID(controllerHandler);
143 if (!controllerHandler->cornerRadiusRect) {
144 return;
145 }
146 NG::BorderRadiusProperty radius;
147 radius.radiusTopLeft = Dimension(controllerHandler->cornerRadiusRect->topLeft, DimensionUnit::VP);
148 radius.radiusTopRight = Dimension(controllerHandler->cornerRadiusRect->topRight, DimensionUnit::VP);
149 radius.radiusBottomLeft = Dimension(controllerHandler->cornerRadiusRect->bottomLeft, DimensionUnit::VP);
150 radius.radiusBottomRight = Dimension(controllerHandler->cornerRadiusRect->bottomRight, DimensionUnit::VP);
151 radius.multiValued = true;
152 dialogProperties.borderRadius = radius;
153 }
154
ParseDialogKeyboardAvoidDistance(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)155 void ParseDialogKeyboardAvoidDistance(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
156 {
157 CHECK_NULL_VOID(controllerHandler);
158 if (!dialogProperties.keyboardAvoidDistance.has_value() &&
159 controllerHandler->keyboardAvoidDistanceValue.has_value()) {
160 auto unitEnum = controllerHandler->keyboardAvoidDistanceUnit;
161 if (controllerHandler->keyboardAvoidDistanceValue.value() < 0 || unitEnum < OHOS::Ace::DimensionUnit::NONE ||
162 unitEnum > OHOS::Ace::DimensionUnit::CALC || unitEnum == OHOS::Ace::DimensionUnit::PERCENT) {
163 dialogProperties.keyboardAvoidDistance = Dimension(DEFAULT_AVOID_DISTANCE, OHOS::Ace::DimensionUnit::VP);
164 } else if (unitEnum == OHOS::Ace::DimensionUnit::NONE) {
165 dialogProperties.keyboardAvoidDistance = Dimension(controllerHandler->keyboardAvoidDistanceValue.value(),
166 OHOS::Ace::DimensionUnit::VP);
167 } else {
168 dialogProperties.keyboardAvoidDistance = Dimension(controllerHandler->keyboardAvoidDistanceValue.value(),
169 unitEnum);
170 }
171 }
172 }
173
ParseDialogProperties(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)174 void ParseDialogProperties(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
175 {
176 CHECK_NULL_VOID(controllerHandler);
177 dialogProperties.autoCancel = controllerHandler->autoCancel;
178 dialogProperties.alignment = GetDialogAlignment(controllerHandler->alignment);
179 dialogProperties.offset = DimensionOffset(Dimension(controllerHandler->offsetX, DimensionUnit::VP),
180 Dimension(controllerHandler->offsetY, DimensionUnit::VP));
181 dialogProperties.isShowInSubWindow = controllerHandler->showInSubWindow;
182 dialogProperties.isModal = controllerHandler->isModal;
183 dialogProperties.backgroundColor = Color(controllerHandler->backgroundColor);
184 dialogProperties.customStyle = controllerHandler->enableCustomStyle;
185 dialogProperties.gridCount = controllerHandler->gridCount;
186 dialogProperties.dialogLevelMode = static_cast<LevelMode>(controllerHandler->levelMode);
187 dialogProperties.dialogLevelUniqueId = controllerHandler->levelUniqueId;
188 dialogProperties.dialogImmersiveMode = static_cast<ImmersiveMode>(controllerHandler->immersiveMode);
189 ParseDialogMask(dialogProperties, controllerHandler);
190 ParseDialogCornerRadiusRect(dialogProperties, controllerHandler);
191 if (controllerHandler->onWillDismissCall) {
192 dialogProperties.onWillDismiss = [controllerHandler](int32_t reason) {
193 CHECK_NULL_VOID(controllerHandler);
194 CHECK_NULL_VOID(controllerHandler->onWillDismissCall);
195 (*(controllerHandler->onWillDismissCall))(reason);
196 };
197 }
198
199 if (controllerHandler->onWillDismissCallByNDK) {
200 dialogProperties.onWillDismissCallByNDK = [controllerHandler](int32_t reason) {
201 ArkUI_DialogDismissEvent event = { controllerHandler->userData, reason, false };
202 controllerHandler->onWillDismissCallByNDK(&event);
203 return event.BlockDismiss;
204 };
205 }
206
207 if (controllerHandler->enableCustomAnimation && !dialogProperties.openAnimation.has_value()) {
208 AnimationOption animation;
209 dialogProperties.openAnimation = animation;
210 }
211 if (controllerHandler->enableCustomAnimation && !dialogProperties.closeAnimation.has_value()) {
212 AnimationOption animation;
213 dialogProperties.closeAnimation = animation;
214 }
215
216 ParseDialogKeyboardAvoidDistance(dialogProperties, controllerHandler);
217 }
218
SetDialogContent(ArkUIDialogHandle controllerHandler,ArkUINodeHandle contentNode)219 ArkUI_Int32 SetDialogContent(ArkUIDialogHandle controllerHandler, ArkUINodeHandle contentNode)
220 {
221 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
222 CHECK_NULL_RETURN(contentNode, ERROR_CODE_PARAM_INVALID);
223 auto* frameNode = reinterpret_cast<FrameNode*>(contentNode);
224 CHECK_NULL_RETURN(frameNode, ERROR_CODE_PARAM_INVALID);
225 frameNode->IncRefCount();
226 controllerHandler->contentHandle = frameNode;
227 return ERROR_CODE_NO_ERROR;
228 }
229
RemoveDialogContent(ArkUIDialogHandle controllerHandler)230 ArkUI_Int32 RemoveDialogContent(ArkUIDialogHandle controllerHandler)
231 {
232 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
233 if (controllerHandler->contentHandle) {
234 auto* frameNode = reinterpret_cast<FrameNode*>(controllerHandler->contentHandle);
235 CHECK_NULL_RETURN(frameNode, ERROR_CODE_PARAM_INVALID);
236 frameNode->DecRefCount();
237 controllerHandler->contentHandle = nullptr;
238 }
239 return ERROR_CODE_NO_ERROR;
240 }
241
SetDialogContentAlignment(ArkUIDialogHandle controllerHandler,ArkUI_Int32 alignment,ArkUI_Float32 offsetX,ArkUI_Float32 offsetY)242 ArkUI_Int32 SetDialogContentAlignment(ArkUIDialogHandle controllerHandler,
243 ArkUI_Int32 alignment, ArkUI_Float32 offsetX, ArkUI_Float32 offsetY)
244 {
245 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
246 if (alignment < DEFAULT_DIALOG_ALIGNMENT || alignment > ARKUI_ALIGNMENT_BOTTOM_END_INDEX) {
247 return ERROR_CODE_PARAM_INVALID;
248 }
249 controllerHandler->alignment = alignment;
250 controllerHandler->offsetX = offsetX;
251 controllerHandler->offsetY = offsetY;
252 return ERROR_CODE_NO_ERROR;
253 }
254
ResetDialogContentAlignment(ArkUIDialogHandle controllerHandler)255 ArkUI_Int32 ResetDialogContentAlignment(ArkUIDialogHandle controllerHandler)
256 {
257 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
258 controllerHandler->alignment = DEFAULT_DIALOG_ALIGNMENT;
259 controllerHandler->offsetX = 0.0f;
260 controllerHandler->offsetY = 0.0f;
261 return ERROR_CODE_NO_ERROR;
262 }
263
SetDialogModalMode(ArkUIDialogHandle controllerHandler,bool isModal)264 ArkUI_Int32 SetDialogModalMode(ArkUIDialogHandle controllerHandler, bool isModal)
265 {
266 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
267 controllerHandler->isModal = isModal;
268 return ERROR_CODE_NO_ERROR;
269 }
270
SetDialogAutoCancel(ArkUIDialogHandle controllerHandler,bool autoCancel)271 ArkUI_Int32 SetDialogAutoCancel(ArkUIDialogHandle controllerHandler, bool autoCancel)
272 {
273 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
274 controllerHandler->autoCancel = autoCancel;
275 return ERROR_CODE_NO_ERROR;
276 }
277
SetDialogMask(ArkUIDialogHandle controllerHandler,ArkUI_Uint32 maskColor,ArkUIRect * rect)278 ArkUI_Int32 SetDialogMask(ArkUIDialogHandle controllerHandler, ArkUI_Uint32 maskColor, ArkUIRect* rect)
279 {
280 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
281 controllerHandler->maskColor = maskColor;
282 if (rect) {
283 controllerHandler->maskRect = new ArkUIRect({ .x = rect->x, .y = rect->y,
284 .width = rect->width, .height = rect->height });
285 }
286 return ERROR_CODE_NO_ERROR;
287 }
288
SetDialogBackgroundColor(ArkUIDialogHandle controllerHandler,ArkUI_Uint32 backgroundColor)289 ArkUI_Int32 SetDialogBackgroundColor(ArkUIDialogHandle controllerHandler, ArkUI_Uint32 backgroundColor)
290 {
291 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
292 controllerHandler->backgroundColor = backgroundColor;
293 return ERROR_CODE_NO_ERROR;
294 }
295
SetDialogCornerRadius(ArkUIDialogHandle controllerHandler,ArkUI_Float32 topLeft,ArkUI_Float32 topRight,ArkUI_Float32 bottomLeft,ArkUI_Float32 bottomRight)296 ArkUI_Int32 SetDialogCornerRadius(ArkUIDialogHandle controllerHandler, ArkUI_Float32 topLeft,
297 ArkUI_Float32 topRight, ArkUI_Float32 bottomLeft, ArkUI_Float32 bottomRight)
298 {
299 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
300 controllerHandler->cornerRadiusRect = new ArkUICornerRadius({ .topLeft = topLeft, .topRight = topRight,
301 .bottomLeft = bottomLeft, .bottomRight = bottomRight });
302 return ERROR_CODE_NO_ERROR;
303 }
304
SetDialogGridColumnCount(ArkUIDialogHandle controllerHandler,ArkUI_Int32 gridCount)305 ArkUI_Int32 SetDialogGridColumnCount(ArkUIDialogHandle controllerHandler, ArkUI_Int32 gridCount)
306 {
307 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
308 controllerHandler->gridCount = gridCount;
309 return ERROR_CODE_NO_ERROR;
310 }
311
EnableDialogCustomStyle(ArkUIDialogHandle controllerHandler,bool enableCustomStyle)312 ArkUI_Int32 EnableDialogCustomStyle(ArkUIDialogHandle controllerHandler, bool enableCustomStyle)
313 {
314 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
315 controllerHandler->enableCustomStyle = enableCustomStyle;
316 return ERROR_CODE_NO_ERROR;
317 }
318
EnableDialogCustomAnimation(ArkUIDialogHandle controllerHandler,bool enableCustomAnimation)319 ArkUI_Int32 EnableDialogCustomAnimation(ArkUIDialogHandle controllerHandler, bool enableCustomAnimation)
320 {
321 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
322 controllerHandler->enableCustomAnimation = enableCustomAnimation;
323 return ERROR_CODE_NO_ERROR;
324 }
325
ShowDialog(ArkUIDialogHandle controllerHandler,bool showInSubWindow)326 ArkUI_Int32 ShowDialog(ArkUIDialogHandle controllerHandler, bool showInSubWindow)
327 {
328 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
329 controllerHandler->showInSubWindow = showInSubWindow;
330 DialogProperties dialogProperties;
331 ParseDialogProperties(dialogProperties, controllerHandler);
332 auto* contentNode = reinterpret_cast<FrameNode*>(controllerHandler->contentHandle);
333 CHECK_NULL_RETURN(contentNode, ERROR_CODE_PARAM_INVALID);
334 auto contentPtr = AceType::Claim<FrameNode>(contentNode);
335 auto dialogNode = CustomDialogControllerModelNG::SetOpenDialogWithNode(dialogProperties, contentPtr);
336 if (dialogNode) {
337 dialogNode->IncRefCount();
338 }
339 controllerHandler->dialogHandle = AceType::RawPtr(dialogNode);
340 return ERROR_CODE_NO_ERROR;
341 }
342
CloseDialog(ArkUIDialogHandle controllerHandler)343 ArkUI_Int32 CloseDialog(ArkUIDialogHandle controllerHandler)
344 {
345 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
346 auto* dialogNode = reinterpret_cast<FrameNode*>(controllerHandler->dialogHandle);
347 CHECK_NULL_RETURN(dialogNode, ERROR_CODE_PARAM_INVALID);
348 CustomDialogControllerModelNG::SetCloseDialogForNDK(dialogNode);
349 if (dialogNode) {
350 dialogNode->DecRefCount();
351 }
352 controllerHandler->dialogHandle = nullptr;
353 return ERROR_CODE_NO_ERROR;
354 }
355
RegisterOnWillDialogDismiss(ArkUIDialogHandle controllerHandler,bool (* eventHandler)(ArkUI_Int32))356 ArkUI_Int32 RegisterOnWillDialogDismiss(ArkUIDialogHandle controllerHandler, bool (*eventHandler)(ArkUI_Int32))
357 {
358 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
359 controllerHandler->onWillDismissCall = eventHandler;
360 return ERROR_CODE_NO_ERROR;
361 }
362
RegisterOnWillDialogDismissWithUserData(ArkUIDialogHandle controllerHandler,void * userData,void (* callback)(ArkUI_DialogDismissEvent * event))363 ArkUI_Int32 RegisterOnWillDialogDismissWithUserData(
364 ArkUIDialogHandle controllerHandler, void* userData, void (*callback)(ArkUI_DialogDismissEvent* event))
365 {
366 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
367 controllerHandler->onWillDismissCallByNDK = callback;
368 controllerHandler->userData = userData;
369 return ERROR_CODE_NO_ERROR;
370 }
371
SetKeyboardAvoidDistance(ArkUIDialogHandle controllerHandler,float distance,ArkUI_Int32 unit)372 ArkUI_Int32 SetKeyboardAvoidDistance(
373 ArkUIDialogHandle controllerHandler, float distance, ArkUI_Int32 unit)
374 {
375 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
376 controllerHandler->keyboardAvoidDistanceValue = distance;
377 controllerHandler->keyboardAvoidDistanceUnit = static_cast<OHOS::Ace::DimensionUnit>(unit);
378 return ERROR_CODE_NO_ERROR;
379 }
380
SetLevelMode(ArkUIDialogHandle controllerHandler,ArkUI_Int32 mode)381 ArkUI_Int32 SetLevelMode(ArkUIDialogHandle controllerHandler, ArkUI_Int32 mode)
382 {
383 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
384 controllerHandler->levelMode = mode;
385 return ERROR_CODE_NO_ERROR;
386 }
387
SetLevelUniqueId(ArkUIDialogHandle controllerHandler,ArkUI_Int32 uniqueId)388 ArkUI_Int32 SetLevelUniqueId(ArkUIDialogHandle controllerHandler, ArkUI_Int32 uniqueId)
389 {
390 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
391 controllerHandler->levelUniqueId = uniqueId;
392 return ERROR_CODE_NO_ERROR;
393 }
394
SetImmersiveMode(ArkUIDialogHandle controllerHandler,ArkUI_Int32 mode)395 ArkUI_Int32 SetImmersiveMode(ArkUIDialogHandle controllerHandler, ArkUI_Int32 mode)
396 {
397 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
398 controllerHandler->immersiveMode = mode;
399 return ERROR_CODE_NO_ERROR;
400 }
401 } // namespace OHOS::Ace::NG::ViewModel
402