• 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     properties.levelOrder = std::make_optional(NG::LevelOrder::ORDER_DEFAULT);
80     auto levelOrderValue = obj->GetProperty("levelOrder");
81     if (!levelOrderValue->IsObject()) {
82         return;
83     }
84     napi_value levelOrderApi = JsConverter::ConvertJsValToNapiValue(levelOrderValue);
85     CHECK_NULL_VOID(levelOrderApi);
86 
87     auto engine = EngineHelper::GetCurrentEngine();
88     CHECK_NULL_VOID(engine);
89     NativeEngine* nativeEngine = engine->GetNativeEngine();
90     CHECK_NULL_VOID(nativeEngine);
91     auto env = reinterpret_cast<napi_env>(nativeEngine);
92     NG::LevelOrder* levelOrder = nullptr;
93     napi_status status = napi_unwrap(env, levelOrderApi, reinterpret_cast<void**>(&levelOrder));
94     if (status != napi_ok || !levelOrder) {
95         LOGE("Failed to unwrap LevelOrder.");
96         return;
97     }
98 
99     double order = levelOrder->GetOrder();
100     properties.levelOrder = std::make_optional(order);
101 }
102 
ParseCustomDialogFocusable(DialogProperties & properties,JSRef<JSObject> obj)103 void ParseCustomDialogFocusable(DialogProperties& properties, JSRef<JSObject> obj)
104 {
105     auto focusableValue = obj->GetProperty("focusable");
106     if (!focusableValue->IsBoolean()) {
107         return;
108     }
109     properties.focusable = focusableValue->ToBoolean();
110 }
111 
112 static std::atomic<int32_t> controllerId = 0;
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 
352     if (this->ownerView_ == nullptr) {
353         return;
354     }
355     auto containerId = this->ownerView_->GetInstanceId();
356     ContainerScope containerScope(containerId);
357     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
358     auto pipelineContext = PipelineContext::GetCurrentContext();
359     CHECK_NULL_VOID(pipelineContext);
360 
361     auto scopedDelegate = EngineHelper::GetCurrentDelegate();
362     if (!scopedDelegate) {
363         // this case usually means there is no foreground container, need to figure out the reason.
364         return;
365     }
366 
367     auto buildFunc = [buildfunc = jsBuilderFunction_, node = frameNode, context = pipelineContext]() {
368         {
369             ACE_SCORING_EVENT("CustomDialog.builder");
370             context->UpdateCurrentActiveNode(node);
371             buildfunc->Execute();
372         }
373     };
374 
375     auto cancelTask = ([cancelCallback = jsCancelFunction_, node = frameNode, context = pipelineContext]() {
376         if (cancelCallback) {
377             ACE_SCORING_EVENT("CustomDialog.cancel");
378             context->UpdateCurrentActiveNode(node);
379             cancelCallback->Execute();
380         }
381     });
382 
383     auto container = Container::Current();
384     if (container && container->IsScenceBoardWindow() && !dialogProperties_.windowScene.Upgrade()) {
385         dialogProperties_.isScenceBoardDialog = true;
386         auto viewNode = this->ownerView_->GetViewNode();
387         CHECK_NULL_VOID(viewNode);
388         auto parentCustom = AceType::DynamicCast<NG::CustomNode>(viewNode);
389         CHECK_NULL_VOID(parentCustom);
390         auto parent = parentCustom->GetParent();
391         while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
392             parent = parent->GetParent();
393         }
394         if (parent) {
395             dialogProperties_.windowScene = parent;
396         }
397     }
398     dialogProperties_.isSysBlurStyle =
399         Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TWELVE) ? true : false;
400     CustomDialogControllerModel::GetInstance()->SetOpenDialog(dialogProperties_, WeakClaim(this), dialogs_, pending_,
401         isShown_, std::move(cancelTask), std::move(buildFunc), dialogComponent_, customDialog_, dialogOperation_);
402 }
403 
JsCloseDialog(const JSCallbackInfo & info)404 void JSCustomDialogController::JsCloseDialog(const JSCallbackInfo& info)
405 {
406 
407     if (this->ownerView_ == nullptr) {
408         return;
409     }
410     auto containerId = this->ownerView_->GetInstanceId();
411     ContainerScope containerScope(containerId);
412 
413     auto scopedDelegate = EngineHelper::GetCurrentDelegate();
414     if (!scopedDelegate) {
415         // this case usually means there is no foreground container, need to figure out the reason.
416         return;
417     }
418 
419     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
420     auto cancelTask = ([cancelCallback = jsCancelFunction_, node = frameNode]() {
421         if (cancelCallback) {
422             ACE_SCORING_EVENT("CustomDialog.cancel");
423             auto pipelineContext = PipelineContext::GetCurrentContext();
424             CHECK_NULL_VOID(pipelineContext);
425             pipelineContext->UpdateCurrentActiveNode(node);
426             cancelCallback->Execute();
427         }
428     });
429 
430     CustomDialogControllerModel::GetInstance()->SetCloseDialog(dialogProperties_, WeakClaim(this), dialogs_, pending_,
431         isShown_, std::move(cancelTask), dialogComponent_, customDialog_, dialogOperation_);
432 }
433 
ParseAnimation(const JsiExecutionContext & execContext,const JsiRef<JsiValue> & animationValue,AnimationOption & result)434 bool JSCustomDialogController::ParseAnimation(
435     const JsiExecutionContext& execContext, const JsiRef<JsiValue>& animationValue, AnimationOption& result)
436 {
437     if (animationValue->IsNull() || !animationValue->IsObject()) {
438         return false;
439     }
440 
441     JSRef<JSObject> obj = JSRef<JSObject>::Cast(animationValue);
442     // If the attribute does not exist, the default value is used.
443     int32_t duration = obj->GetPropertyValue<int32_t>("duration", DEFAULT_ANIMATION_DURATION);
444     int32_t delay = obj->GetPropertyValue<int32_t>("delay", 0);
445     int32_t iterations = obj->GetPropertyValue<int32_t>("iterations", 1);
446     float tempo = obj->GetPropertyValue<float>("tempo", 1.0);
447     auto finishCallbackType = static_cast<FinishCallbackType>(obj->GetPropertyValue<int32_t>("finishCallbackType", 0));
448     if (tempo < 0) {
449         tempo = 1.0f;
450     } else if (tempo == 0) {
451         tempo = 1000.0f;
452     }
453     auto direction = StringToAnimationDirection(obj->GetPropertyValue<std::string>("playMode", "normal"));
454     RefPtr<Curve> curve;
455     JSRef<JSVal> curveArgs = obj->GetProperty("curve");
456     if (curveArgs->IsString()) {
457         curve = CreateCurve(obj->GetPropertyValue<std::string>("curve", "linear"));
458     } else if (curveArgs->IsObject()) {
459         JSRef<JSObject> curveObj = JSRef<JSObject>::Cast(curveArgs);
460         JSRef<JSVal> curveString = curveObj->GetProperty("__curveString");
461         if (!curveString->IsString()) {
462             // Default AnimationOption which is invalid.
463             return false;
464         }
465         curve = CreateCurve(curveString->ToString());
466     } else {
467         curve = Curves::EASE_IN_OUT;
468     }
469     result.SetDuration(duration);
470     result.SetDelay(delay);
471     result.SetIteration(iterations);
472     result.SetTempo(tempo);
473     result.SetAnimationDirection(direction);
474     result.SetCurve(curve);
475     result.SetFinishCallbackType(finishCallbackType);
476 
477     JSRef<JSVal> onFinish = obj->GetProperty("onFinish");
478     std::function<void()> onFinishEvent;
479     if (onFinish->IsFunction()) {
480         auto frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
481         auto jsFunc = AceType::MakeRefPtr<JsWeakFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onFinish));
482         onFinishEvent = [execCtx = execContext, func = std::move(jsFunc), node = frameNode]() {
483             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
484             ACE_SCORING_EVENT("CustomDialog.onFinish");
485             auto pipelineContext = PipelineContext::GetCurrentContext();
486             CHECK_NULL_VOID(pipelineContext);
487             pipelineContext->UpdateCurrentActiveNode(node);
488             func->Execute();
489         };
490         result.SetOnFinishEvent(onFinishEvent);
491     }
492     return true;
493 }
494 
JSBind(BindingTarget object)495 void JSCustomDialogController::JSBind(BindingTarget object)
496 {
497     JSClass<JSCustomDialogController>::Declare("NativeCustomDialogController");
498     JSClass<JSCustomDialogController>::CustomMethod("open", &JSCustomDialogController::JsOpenDialog);
499     JSClass<JSCustomDialogController>::CustomMethod("close", &JSCustomDialogController::JsCloseDialog);
500     JSClass<JSCustomDialogController>::Bind(
501         object, &JSCustomDialogController::ConstructorCallback, &JSCustomDialogController::DestructorCallback);
502 }
503 } // namespace OHOS::Ace::Framework
504