• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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/declarative_frontend/jsview/dialog/js_custom_dialog_controller.h"
17 
18 #include "bridge/declarative_frontend/engine/js_converter.h"
19 
20 #include "base/subwindow/subwindow_manager.h"
21 #include "base/utils/system_properties.h"
22 #include "base/utils/utils.h"
23 #include "bridge/declarative_frontend/engine/jsi/jsi_types.h"
24 #include "bridge/declarative_frontend/jsview/js_view.h"
25 #include "bridge/declarative_frontend/jsview/models/custom_dialog_controller_model_impl.h"
26 #include "core/common/ace_engine.h"
27 #include "core/common/container.h"
28 #include "core/components_ng/base/view_stack_processor.h"
29 #include "core/components_ng/pattern/dialog/custom_dialog_controller_model_ng.h"
30 #include "core/components_ng/pattern/overlay/level_order.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 #include "frameworks/bridge/common/utils/engine_helper.h"
33 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
34 #include "frameworks/bridge/declarative_frontend/engine/jsi/js_ui_index.h"
35 
36 namespace OHOS::Ace {
37 std::unique_ptr<CustomDialogControllerModel> CustomDialogControllerModel::instance_ = nullptr;
38 std::mutex CustomDialogControllerModel::mutex_;
GetInstance()39 CustomDialogControllerModel* CustomDialogControllerModel::GetInstance()
40 {
41     if (!instance_) {
42         std::lock_guard<std::mutex> lock(mutex_);
43         if (!instance_) {
44 #ifdef NG_BUILD
45             instance_.reset(new NG::CustomDialogControllerModelNG());
46 #else
47             if (Container::IsCurrentUseNewPipeline()) {
48                 instance_.reset(new NG::CustomDialogControllerModelNG());
49             } else {
50                 instance_.reset(new Framework::CustomDialogControllerModelImpl());
51             }
52 #endif
53         }
54     }
55     return instance_.get();
56 }
57 } // namespace OHOS::Ace
58 
59 namespace OHOS::Ace::Framework {
60 namespace {
61 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
62     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
63     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
64     DialogAlignment::BOTTOM_END };
65 const std::vector<KeyboardAvoidMode> KEYBOARD_AVOID_MODE = { KeyboardAvoidMode::DEFAULT, KeyboardAvoidMode::NONE };
66 const std::vector<LevelMode> DIALOG_LEVEL_MODE = { LevelMode::OVERLAY, LevelMode::EMBEDDED };
67 const std::vector<ImmersiveMode> DIALOG_IMMERSIVE_MODE = { ImmersiveMode::DEFAULT, ImmersiveMode::EXTEND };
68 constexpr int32_t DEFAULT_ANIMATION_DURATION = 200;
69 constexpr float DEFAULT_AVOID_DISTANCE = 16.0f;
70 
71 } // namespace
72 
ParseCustomDialogLevelOrder(DialogProperties & properties,JSRef<JSObject> obj)73 void ParseCustomDialogLevelOrder(DialogProperties& properties, JSRef<JSObject> obj)
74 {
75     if (properties.isShowInSubWindow) {
76         return;
77     }
78 
79     auto levelOrderValue = obj->GetProperty("levelOrder");
80     if (!levelOrderValue->IsObject()) {
81         return;
82     }
83     napi_value levelOrderApi = JsConverter::ConvertJsValToNapiValue(levelOrderValue);
84     CHECK_NULL_VOID(levelOrderApi);
85 
86     auto engine = EngineHelper::GetCurrentEngine();
87     CHECK_NULL_VOID(engine);
88     NativeEngine* nativeEngine = engine->GetNativeEngine();
89     CHECK_NULL_VOID(nativeEngine);
90     auto env = reinterpret_cast<napi_env>(nativeEngine);
91     NG::LevelOrder* levelOrder = nullptr;
92     napi_status status = napi_unwrap(env, levelOrderApi, reinterpret_cast<void**>(&levelOrder));
93     if (status != napi_ok || !levelOrder) {
94         LOGE("Failed to unwrap LevelOrder.");
95         return;
96     }
97 
98     double order = levelOrder->GetOrder();
99     properties.levelOrder = std::make_optional(order);
100 }
101 
ParseCustomDialogFocusable(DialogProperties & properties,JSRef<JSObject> obj)102 void ParseCustomDialogFocusable(DialogProperties& properties, JSRef<JSObject> obj)
103 {
104     auto focusableValue = obj->GetProperty("focusable");
105     if (!focusableValue->IsBoolean()) {
106         return;
107     }
108     properties.focusable = focusableValue->ToBoolean();
109 }
110 
111 static std::atomic<int32_t> controllerId = 0;
112 
ConstructorCallback(const JSCallbackInfo & info)113 void JSCustomDialogController::ConstructorCallback(const JSCallbackInfo& info)
114 {
115     uint32_t argc = info.Length();
116     if (argc > 1 && !info[0]->IsUndefined() && info[0]->IsObject() && !info[1]->IsUndefined() && info[1]->IsObject()) {
117         JSRef<JSObject> constructorArg = JSRef<JSObject>::Cast(info[0]);
118         JSRef<JSObject> ownerObj = JSRef<JSObject>::Cast(info[1]);
119 
120         // check if owner object is set
121         auto* ownerView = JSView::GetNativeView(ownerObj);
122         auto instance = AceType::MakeRefPtr<JSCustomDialogController>(ownerView);
123         if (ownerView == nullptr) {
124             instance->IncRefCount();
125             info.SetReturnValue(AceType::RawPtr(instance));
126             instance = nullptr;
127             return;
128         }
129 
130         // Process builder function.
131         JSRef<JSVal> builderCallback = constructorArg->GetProperty("builder");
132         if (!builderCallback->IsUndefined() && builderCallback->IsFunction()) {
133             instance->jsBuilderFunction_ =
134                 AceType::MakeRefPtr<JsWeakFunction>(ownerObj, JSRef<JSFunc>::Cast(builderCallback));
135         } else {
136             instance->jsBuilderFunction_ = nullptr;
137             instance->IncRefCount();
138             info.SetReturnValue(AceType::RawPtr(instance));
139             instance = nullptr;
140             return;
141         }
142 
143         // Process cancel function.
144         JSRef<JSVal> cancelCallback = constructorArg->GetProperty("cancel");
145         if (!cancelCallback->IsUndefined() && cancelCallback->IsFunction()) {
146             auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
147             auto jsCancelFunction = AceType::MakeRefPtr<JsWeakFunction>(ownerObj, JSRef<JSFunc>::Cast(cancelCallback));
148             instance->jsCancelFunction_ = jsCancelFunction;
149 
150             auto onCancel = [execCtx = info.GetExecutionContext(), func = std::move(jsCancelFunction),
151                                 node = frameNode]() {
152                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
153                 ACE_SCORING_EVENT("onCancel");
154                 auto pipelineContext = PipelineContext::GetCurrentContext();
155                 CHECK_NULL_VOID(pipelineContext);
156                 pipelineContext->UpdateCurrentActiveNode(node);
157                 func->Execute();
158             };
159             instance->dialogProperties_.onCancel = onCancel;
160         }
161 
162         std::function<void(const int32_t& info, const int32_t& instanceId)> onWillDismissFunc = nullptr;
163         JSViewAbstract::ParseDialogCallback(constructorArg, onWillDismissFunc);
164         instance->dialogProperties_.onWillDismiss = onWillDismissFunc;
165 
166         JSViewAbstract::ParseAppearDialogCallback(info, instance->dialogProperties_);
167 
168         // Parses autoCancel.
169         JSRef<JSVal> autoCancelValue = constructorArg->GetProperty("autoCancel");
170         if (autoCancelValue->IsBoolean()) {
171             instance->dialogProperties_.autoCancel = autoCancelValue->ToBoolean();
172         }
173 
174         // Parses customStyle.
175         JSRef<JSVal> customStyleValue = constructorArg->GetProperty("customStyle");
176         if (customStyleValue->IsBoolean()) {
177             instance->dialogProperties_.customStyle = customStyleValue->ToBoolean();
178         }
179 
180         // Parse alignment
181         auto alignmentValue = constructorArg->GetProperty("alignment");
182         if (alignmentValue->IsNumber()) {
183             auto alignment = alignmentValue->ToNumber<int32_t>();
184             if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
185                 instance->dialogProperties_.alignment = DIALOG_ALIGNMENT[alignment];
186             }
187         }
188 
189         // Parse keyboardAvoidMode
190         auto avoidModeValue = constructorArg->GetProperty("keyboardAvoidMode");
191         if (avoidModeValue->IsNumber()) {
192             auto avoidMode = avoidModeValue->ToNumber<int32_t>();
193             if (avoidMode >= 0 && avoidMode < static_cast<int32_t>(KEYBOARD_AVOID_MODE.size())) {
194                 instance->dialogProperties_.keyboardAvoidMode = KEYBOARD_AVOID_MODE[avoidMode];
195             }
196         }
197 
198         // Parse keyboardAvoidDistance
199         auto avoidDistance = constructorArg->GetProperty("keyboardAvoidDistance");
200         if (avoidDistance->IsObject()) {
201             JSRef<JSObject> avoidDistanceobj = JSRef<JSObject>::Cast(avoidDistance);
202             auto avoidDisValue = avoidDistanceobj->GetProperty(static_cast<int32_t>(ArkUIIndex::VALUE));
203             auto jsAvoidDisUnit = avoidDistanceobj->GetProperty(static_cast<int32_t>(ArkUIIndex::UNIT));
204             DimensionUnit avoidDisUnit = OHOS::Ace::DimensionUnit::VP;
205             if (jsAvoidDisUnit->IsNumber()) {
206                 avoidDisUnit = static_cast<DimensionUnit>(jsAvoidDisUnit->ToNumber<int32_t>());
207             }
208             if (avoidDisValue->IsNumber() && avoidDisValue->ToNumber<double>() >= 0 &&
209                 avoidDisUnit >= OHOS::Ace::DimensionUnit::PX && avoidDisUnit <= OHOS::Ace::DimensionUnit::CALC &&
210                 avoidDisUnit != OHOS::Ace::DimensionUnit::PERCENT) {
211                 Dimension avoidDistanceDimension(avoidDisValue->ToNumber<double>(), avoidDisUnit);
212                 instance->dialogProperties_.keyboardAvoidDistance = avoidDistanceDimension;
213             } else {
214                 Dimension avoidDistanceDimension(DEFAULT_AVOID_DISTANCE, OHOS::Ace::DimensionUnit::VP);
215                 instance->dialogProperties_.keyboardAvoidDistance = avoidDistanceDimension;
216             }
217         }
218 
219         // Parse offset
220         auto offsetValue = constructorArg->GetProperty("offset");
221         if (offsetValue->IsObject()) {
222             auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
223             CalcDimension dx;
224             auto dxValue = offsetObj->GetProperty("dx");
225             JSViewAbstract::ParseJsDimensionVp(dxValue, dx);
226             CalcDimension dy;
227             auto dyValue = offsetObj->GetProperty("dy");
228             JSViewAbstract::ParseJsDimensionVp(dyValue, dy);
229             dx.ResetInvalidValue();
230             dy.ResetInvalidValue();
231             instance->dialogProperties_.offset = DimensionOffset(dx, dy);
232         }
233 
234         // Parses gridCount.
235         auto gridCountValue = constructorArg->GetProperty("gridCount");
236         if (gridCountValue->IsNumber()) {
237             instance->dialogProperties_.gridCount = gridCountValue->ToNumber<int32_t>();
238         }
239 
240         // Parse maskColor.
241         auto maskColorValue = constructorArg->GetProperty("maskColor");
242         Color maskColor;
243         if (JSViewAbstract::ParseJsColor(maskColorValue, maskColor)) {
244             instance->dialogProperties_.maskColor = maskColor;
245         }
246 
247         // Parse maskRect.
248         auto maskRectValue = constructorArg->GetProperty("maskRect");
249         DimensionRect maskRect;
250         if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
251             instance->dialogProperties_.maskRect = maskRect;
252         }
253 
254         // Parse backgroundColor.
255         auto backgroundColorValue = constructorArg->GetProperty("backgroundColor");
256         Color backgroundColor;
257         if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
258             instance->dialogProperties_.backgroundColor = backgroundColor;
259         }
260 
261         // Parse backgroundBlurStyle.
262         auto backgroundBlurStyle = constructorArg->GetProperty("backgroundBlurStyle");
263         if (backgroundBlurStyle->IsNumber()) {
264             auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
265             if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
266                 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
267                 instance->dialogProperties_.backgroundBlurStyle = blurStyle;
268             }
269         }
270 
271         auto execContext = info.GetExecutionContext();
272         // Parse openAnimation.
273         auto openAnimationValue = constructorArg->GetProperty("openAnimation");
274         AnimationOption openAnimation;
275         if (ParseAnimation(execContext, openAnimationValue, openAnimation)) {
276             instance->dialogProperties_.openAnimation = openAnimation;
277         }
278 
279         // Parse closeAnimation.
280         auto closeAnimationValue = constructorArg->GetProperty("closeAnimation");
281         AnimationOption closeAnimation;
282         if (ParseAnimation(execContext, closeAnimationValue, closeAnimation)) {
283             instance->dialogProperties_.closeAnimation = closeAnimation;
284         }
285 
286         // Parse showInSubWindowValue.
287         auto showInSubWindowValue = constructorArg->GetProperty("showInSubWindow");
288         if (showInSubWindowValue->IsBoolean()) {
289 #if defined(PREVIEW)
290             LOGW("[Engine Log] Unable to use the SubWindow in the Previewer. Perform this operation on the "
291                  "emulator or a real device instead.");
292 #else
293             instance->dialogProperties_.isShowInSubWindow = showInSubWindowValue->ToBoolean();
294 #endif
295         }
296 
297         auto dialogLevelMode = constructorArg->GetProperty("levelMode");
298         if (dialogLevelMode->IsNumber() && !instance->dialogProperties_.isShowInSubWindow) {
299             auto levelMode = dialogLevelMode->ToNumber<int32_t>();
300             if (levelMode >= 0 && levelMode < static_cast<int32_t>(DIALOG_LEVEL_MODE.size())) {
301                 instance->dialogProperties_.dialogLevelMode = DIALOG_LEVEL_MODE[levelMode];
302             }
303         }
304 
305         auto dialogLevelUniqueId = constructorArg->GetProperty("levelUniqueId");
306         if (dialogLevelUniqueId->IsNumber()) {
307             instance->dialogProperties_.dialogLevelUniqueId = dialogLevelUniqueId->ToNumber<int32_t>();
308         }
309 
310         auto immersiveMode = constructorArg->GetProperty("immersiveMode");
311         if (immersiveMode->IsNumber()) {
312             auto immersiveVal = immersiveMode->ToNumber<int32_t>();
313             if (immersiveVal >= 0 && immersiveVal < static_cast<int32_t>(DIALOG_IMMERSIVE_MODE.size())) {
314                 instance->dialogProperties_.dialogImmersiveMode = DIALOG_IMMERSIVE_MODE[immersiveVal];
315             }
316         }
317 
318         // Parse isModal.
319         auto isModalValue = constructorArg->GetProperty("isModal");
320         if (isModalValue->IsBoolean()) {
321             instance->dialogProperties_.isModal = isModalValue->ToBoolean();
322         }
323 
324         // Parse levelOrder.
325         ParseCustomDialogLevelOrder(instance->dialogProperties_, constructorArg);
326         ParseCustomDialogFocusable(instance->dialogProperties_, constructorArg);
327 
328         instance->dialogProperties_.controllerId = controllerId.fetch_add(1, std::memory_order_relaxed);
329         JSViewAbstract::SetDialogProperties(constructorArg, instance->dialogProperties_);
330         JSViewAbstract::SetDialogHoverModeProperties(constructorArg, instance->dialogProperties_);
331         JSViewAbstract::SetDialogBlurStyleOption(constructorArg, instance->dialogProperties_);
332         JSViewAbstract::SetDialogEffectOption(constructorArg, instance->dialogProperties_);
333         instance->IncRefCount();
334         info.SetReturnValue(AceType::RawPtr(instance));
335     }
336 }
337 
DestructorCallback(JSCustomDialogController * controller)338 void JSCustomDialogController::DestructorCallback(JSCustomDialogController* controller)
339 {
340     if (controller != nullptr) {
341         controller->ownerView_ = nullptr;
342         controller->DecRefCount();
343     }
344 }
345 
JsOpenDialog(const JSCallbackInfo & info)346 void JSCustomDialogController::JsOpenDialog(const JSCallbackInfo& info)
347 {
348     if (!jsBuilderFunction_) {
349         return;
350     }
351     if (this->ownerView_ == nullptr) {
352         return;
353     }
354     auto containerId = this->ownerView_->GetInstanceId();
355     ContainerScope containerScope(containerId);
356     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
357     auto pipelineContext = PipelineContext::GetCurrentContext();
358     CHECK_NULL_VOID(pipelineContext);
359 
360     auto scopedDelegate = EngineHelper::GetCurrentDelegate();
361     if (!scopedDelegate) {
362         // this case usually means there is no foreground container, need to figure out the reason.
363         return;
364     }
365 
366     auto buildFunc = [buildfunc = jsBuilderFunction_, node = frameNode, context = pipelineContext]() {
367         {
368             ACE_SCORING_EVENT("CustomDialog.builder");
369             context->UpdateCurrentActiveNode(node);
370             buildfunc->Execute();
371         }
372     };
373 
374     auto cancelTask = ([cancelCallback = jsCancelFunction_, node = frameNode, context = pipelineContext]() {
375         if (cancelCallback) {
376             ACE_SCORING_EVENT("CustomDialog.cancel");
377             context->UpdateCurrentActiveNode(node);
378             cancelCallback->Execute();
379         }
380     });
381 
382     auto container = Container::Current();
383     if (container && container->IsSceneBoardWindow() && !dialogProperties_.windowScene.Upgrade()) {
384         dialogProperties_.isSceneBoardDialog = true;
385         auto viewNode = this->ownerView_->GetViewNode();
386         CHECK_NULL_VOID(viewNode);
387         auto parentCustom = AceType::DynamicCast<NG::CustomNode>(viewNode);
388         CHECK_NULL_VOID(parentCustom);
389         auto parent = parentCustom->GetParent();
390         while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
391             parent = parent->GetParent();
392         }
393         if (parent) {
394             dialogProperties_.windowScene = parent;
395         }
396     }
397     dialogProperties_.isSysBlurStyle =
398         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TWELVE) ? true : false;
399     CustomDialogControllerModel::GetInstance()->SetOpenDialog(dialogProperties_, WeakClaim(this), dialogs_, pending_,
400         isShown_, std::move(cancelTask), std::move(buildFunc), dialogComponent_, customDialog_, dialogOperation_,
401         hasBind_);
402 }
403 
JsCloseDialog(const JSCallbackInfo & info)404 void JSCustomDialogController::JsCloseDialog(const JSCallbackInfo& info)
405 {
406     if (this->ownerView_ == nullptr) {
407         return;
408     }
409     auto containerId = this->ownerView_->GetInstanceId();
410     ContainerScope containerScope(containerId);
411 
412     auto scopedDelegate = EngineHelper::GetCurrentDelegate();
413     if (!scopedDelegate) {
414         // this case usually means there is no foreground container, need to figure out the reason.
415         return;
416     }
417 
418     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
419     auto cancelTask = ([cancelCallback = jsCancelFunction_, node = frameNode]() {
420         if (cancelCallback) {
421             ACE_SCORING_EVENT("CustomDialog.cancel");
422             auto pipelineContext = PipelineContext::GetCurrentContext();
423             CHECK_NULL_VOID(pipelineContext);
424             pipelineContext->UpdateCurrentActiveNode(node);
425             cancelCallback->Execute();
426         }
427     });
428 
429     CustomDialogControllerModel::GetInstance()->SetCloseDialog(dialogProperties_, WeakClaim(this), dialogs_, pending_,
430         isShown_, std::move(cancelTask), dialogComponent_, customDialog_, dialogOperation_);
431 }
432 
JsGetState(const JSCallbackInfo & info)433 void JSCustomDialogController::JsGetState(const JSCallbackInfo& info)
434 {
435     PromptActionCommonState state = CustomDialogControllerModel::GetInstance()->GetState(dialogs_, hasBind_);
436     info.SetReturnValue(JSRef<JSVal>::Make(ToJSValue(static_cast<int32_t>(state))));
437 }
438 
ParseAnimation(const JsiExecutionContext & execContext,const JsiRef<JsiValue> & animationValue,AnimationOption & result)439 bool JSCustomDialogController::ParseAnimation(
440     const JsiExecutionContext& execContext, const JsiRef<JsiValue>& animationValue, AnimationOption& result)
441 {
442     if (animationValue->IsNull() || !animationValue->IsObject()) {
443         return false;
444     }
445 
446     JSRef<JSObject> obj = JSRef<JSObject>::Cast(animationValue);
447     // If the attribute does not exist, the default value is used.
448     int32_t duration = obj->GetPropertyValue<int32_t>("duration", DEFAULT_ANIMATION_DURATION);
449     int32_t delay = obj->GetPropertyValue<int32_t>("delay", 0);
450     int32_t iterations = obj->GetPropertyValue<int32_t>("iterations", 1);
451     float tempo = obj->GetPropertyValue<float>("tempo", 1.0);
452     auto finishCallbackType = static_cast<FinishCallbackType>(obj->GetPropertyValue<int32_t>("finishCallbackType", 0));
453     if (tempo < 0) {
454         tempo = 1.0f;
455     } else if (tempo == 0) {
456         tempo = 1000.0f;
457     }
458     auto direction = StringToAnimationDirection(obj->GetPropertyValue<std::string>("playMode", "normal"));
459     RefPtr<Curve> curve;
460     JSRef<JSVal> curveArgs = obj->GetProperty("curve");
461     if (curveArgs->IsString()) {
462         curve = CreateCurve(obj->GetPropertyValue<std::string>("curve", "linear"));
463     } else if (curveArgs->IsObject()) {
464         JSRef<JSObject> curveObj = JSRef<JSObject>::Cast(curveArgs);
465         JSRef<JSVal> curveString = curveObj->GetProperty("__curveString");
466         if (!curveString->IsString()) {
467             // Default AnimationOption which is invalid.
468             return false;
469         }
470         curve = CreateCurve(curveString->ToString());
471     } else {
472         curve = Curves::EASE_IN_OUT;
473     }
474     result.SetDuration(duration);
475     result.SetDelay(delay);
476     result.SetIteration(iterations);
477     result.SetTempo(tempo);
478     result.SetAnimationDirection(direction);
479     result.SetCurve(curve);
480     result.SetFinishCallbackType(finishCallbackType);
481 
482     JSRef<JSVal> onFinish = obj->GetProperty("onFinish");
483     std::function<void()> onFinishEvent;
484     if (onFinish->IsFunction()) {
485         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
486         auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
487         onFinishEvent = [execCtx = execContext, func = std::move(jsFunc), node = frameNode]() {
488             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
489             ACE_SCORING_EVENT("CustomDialog.onFinish");
490             auto pipelineContext = PipelineContext::GetCurrentContext();
491             CHECK_NULL_VOID(pipelineContext);
492             pipelineContext->UpdateCurrentActiveNode(node);
493             func->Execute();
494         };
495         result.SetOnFinishEvent(onFinishEvent);
496     }
497     return true;
498 }
499 
JSBind(BindingTarget object)500 void JSCustomDialogController::JSBind(BindingTarget object)
501 {
502     JSClass<JSCustomDialogController>::Declare("NativeCustomDialogController");
503     JSClass<JSCustomDialogController>::CustomMethod("open", &JSCustomDialogController::JsOpenDialog);
504     JSClass<JSCustomDialogController>::CustomMethod("close", &JSCustomDialogController::JsCloseDialog);
505     JSClass<JSCustomDialogController>::CustomMethod("getState", &JSCustomDialogController::JsGetState);
506     JSClass<JSCustomDialogController>::Bind(
507         object, &JSCustomDialogController::ConstructorCallback, &JSCustomDialogController::DestructorCallback);
508 }
509 } // namespace OHOS::Ace::Framework
510