1 /*
2 * Copyright (c) 2023 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/components_ng/pattern/dialog/custom_dialog_controller_model_ng.h"
16 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
17 #include "core/components_ng/pattern/overlay/dialog_manager.h"
18
19 #include "base/memory/ace_type.h"
20 #include "base/subwindow/subwindow_manager.h"
21 #include "base/thread/task_executor.h"
22 #include "core/common/container_scope.h"
23
24 namespace OHOS::Ace::NG {
SetOpenDialog(DialogProperties & dialogProperties,const WeakPtr<AceType> & controller,std::vector<WeakPtr<AceType>> & dialogs,bool & pending,bool & isShown,std::function<void ()> && cancelTask,std::function<void ()> && buildFunc,RefPtr<AceType> & dialogComponent,RefPtr<AceType> & customDialog,std::list<DialogOperation> & dialogOperation)25 void CustomDialogControllerModelNG::SetOpenDialog(DialogProperties& dialogProperties,
26 const WeakPtr<AceType>& controller, std::vector<WeakPtr<AceType>>& dialogs,
27 bool& pending, bool& isShown, std::function<void()>&& cancelTask, std::function<void()>&& buildFunc,
28 RefPtr<AceType>& dialogComponent, RefPtr<AceType>& customDialog, std::list<DialogOperation>& dialogOperation)
29 {
30 auto container = Container::Current();
31 auto currentId = Container::CurrentId();
32 CHECK_NULL_VOID(container);
33 if (container->IsSubContainer() && !dialogProperties.isShowInSubWindow) {
34 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
35 container = AceEngine::Get().GetContainer(currentId);
36 CHECK_NULL_VOID(container);
37 }
38 ContainerScope scope(currentId);
39 auto pipelineContext = container->GetPipelineContext();
40 CHECK_NULL_VOID(pipelineContext);
41 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
42 CHECK_NULL_VOID(context);
43 auto overlayManager = context->GetOverlayManager();
44 CHECK_NULL_VOID(overlayManager);
45 if (dialogProperties.dialogLevelMode == LevelMode::EMBEDDED) {
46 auto embeddedOverlay = NG::DialogManager::GetEmbeddedOverlay(dialogProperties.dialogLevelUniqueId, context);
47 if (embeddedOverlay) {
48 overlayManager = embeddedOverlay;
49 }
50 }
51 dialogProperties.onStatusChanged = [&isShown](bool isShownStatus) {
52 if (!isShownStatus) {
53 isShown = isShownStatus;
54 }
55 };
56
57 auto executor = context->GetTaskExecutor();
58 if (!executor) {
59 TAG_LOGE(AceLogTag::ACE_DIALOG, "Task executor is null.");
60 return;
61 }
62 auto task = [currentId, controller, &dialogProperties, &dialogs, func = std::move(buildFunc),
63 weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager))]() mutable {
64 ContainerScope scope(currentId);
65 RefPtr<NG::FrameNode> dialog;
66 auto overlayManager = weakOverlayManager.Upgrade();
67 CHECK_NULL_VOID(overlayManager);
68 auto controllerPtr = controller.Upgrade();
69 CHECK_NULL_VOID(controllerPtr);
70 auto container = Container::Current();
71 CHECK_NULL_VOID(container);
72 if (dialogProperties.isShowInSubWindow) {
73 dialog = SubwindowManager::GetInstance()->ShowDialogNG(dialogProperties, std::move(func));
74 CHECK_NULL_VOID(dialog);
75 if (dialogProperties.isModal && !dialogProperties.isScenceBoardDialog &&
76 !container->IsUIExtensionWindow()) {
77 auto mask = overlayManager->SetDialogMask(dialogProperties);
78 CHECK_NULL_VOID(mask);
79 overlayManager->SetMaskNodeId(dialog->GetId(), mask->GetId());
80 }
81 } else {
82 dialog = overlayManager->ShowDialog(dialogProperties, std::move(func), false);
83 }
84 CHECK_NULL_VOID(dialog);
85 dialogs.emplace_back(dialog);
86 };
87 executor->PostTask(task, TaskExecutor::TaskType::UI, "ArkUIDialogShowCustomDialog");
88 }
89
SetOpenDialogWithNode(DialogProperties & dialogProperties,const RefPtr<UINode> & customNode)90 RefPtr<UINode> CustomDialogControllerModelNG::SetOpenDialogWithNode(DialogProperties& dialogProperties,
91 const RefPtr<UINode>& customNode)
92 {
93 ContainerScope scope(Container::CurrentIdSafely());
94 auto container = Container::Current();
95 CHECK_NULL_RETURN(container, nullptr);
96 if (container->IsSubContainer() && !dialogProperties.isShowInSubWindow) {
97 auto currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
98 container = AceEngine::Get().GetContainer(currentId);
99 CHECK_NULL_RETURN(container, nullptr);
100 }
101 auto pipelineContext = container->GetPipelineContext();
102 CHECK_NULL_RETURN(pipelineContext, nullptr);
103 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
104 CHECK_NULL_RETURN(context, nullptr);
105 auto overlayManager = context->GetOverlayManager();
106 CHECK_NULL_RETURN(overlayManager, nullptr);
107 if (dialogProperties.dialogLevelMode == LevelMode::EMBEDDED) {
108 auto embeddedOverlay = NG::DialogManager::GetEmbeddedOverlay(dialogProperties.dialogLevelUniqueId, context);
109 if (embeddedOverlay) {
110 overlayManager = embeddedOverlay;
111 }
112 }
113 RefPtr<NG::FrameNode> dialog;
114 if (dialogProperties.isShowInSubWindow) {
115 dialog = SubwindowManager::GetInstance()->ShowDialogNGWithNode(dialogProperties, customNode);
116 if (dialogProperties.isModal && !dialogProperties.isScenceBoardDialog && !container->IsUIExtensionWindow()) {
117 DialogProperties Maskarg;
118 Maskarg.isMask = true;
119 Maskarg.autoCancel = dialogProperties.autoCancel;
120 Maskarg.maskColor = dialogProperties.maskColor;
121 auto mask = overlayManager->ShowDialogWithNode(Maskarg, nullptr, false);
122 CHECK_NULL_RETURN(mask, dialog);
123 overlayManager->SetMaskNodeId(dialog->GetId(), mask->GetId());
124 }
125 } else {
126 dialog = overlayManager->ShowDialogWithNode(dialogProperties, customNode, false);
127 }
128 return dialog;
129 }
130
SetCloseDialog(DialogProperties & dialogProperties,const WeakPtr<AceType> & controller,std::vector<WeakPtr<AceType>> & dialogs,bool & pending,bool & isShown,std::function<void ()> && cancelTask,RefPtr<AceType> & dialogComponent,RefPtr<AceType> & customDialog,std::list<DialogOperation> & dialogOperation)131 void CustomDialogControllerModelNG::SetCloseDialog(DialogProperties& dialogProperties,
132 const WeakPtr<AceType>& controller, std::vector<WeakPtr<AceType>>& dialogs,
133 bool& pending, bool& isShown, std::function<void()>&& cancelTask, RefPtr<AceType>& dialogComponent,
134 RefPtr<AceType>& customDialog, std::list<DialogOperation>& dialogOperation)
135 {
136 auto container = Container::Current();
137 auto currentId = Container::CurrentId();
138 CHECK_NULL_VOID(container);
139 if (container->IsSubContainer() && !dialogProperties.isShowInSubWindow) {
140 currentId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
141 container = AceEngine::Get().GetContainer(currentId);
142 CHECK_NULL_VOID(container);
143 }
144 ContainerScope scope(currentId);
145 auto pipelineContext = container->GetPipelineContext();
146 CHECK_NULL_VOID(pipelineContext);
147 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
148 CHECK_NULL_VOID(context);
149 auto overlayManager = context->GetOverlayManager();
150 CHECK_NULL_VOID(overlayManager);
151 auto executor = context->GetTaskExecutor();
152 CHECK_NULL_VOID(executor);
153 auto task = [controller, &dialogs, &dialogProperties,
154 weakOverlayManager = AceType::WeakClaim(AceType::RawPtr(overlayManager))]() {
155 auto overlayManager = weakOverlayManager.Upgrade();
156 CHECK_NULL_VOID(overlayManager);
157 auto controllerPtr = controller.Upgrade();
158 CHECK_NULL_VOID(controllerPtr);
159 RefPtr<NG::FrameNode> dialog;
160 while (!dialogs.empty()) {
161 dialog = AceType::DynamicCast<NG::FrameNode>(dialogs.back().Upgrade());
162 if (dialog && !dialog->IsRemoving()) {
163 // get the dialog not removed currently
164 break;
165 }
166 dialogs.pop_back();
167 }
168 if (dialogs.empty()) {
169 return;
170 }
171 CHECK_NULL_VOID(dialog);
172 if (dialogProperties.isShowInSubWindow) {
173 SubwindowManager::GetInstance()->CloseDialogNG(dialog);
174 dialogs.pop_back();
175 } else {
176 auto dialogPattern = dialog->GetPattern<DialogPattern>();
177 if (dialogProperties.dialogLevelMode == LevelMode::EMBEDDED && dialogPattern) {
178 overlayManager = dialogPattern->GetEmbeddedOverlay(overlayManager);
179 }
180 overlayManager->CloseDialog(dialog);
181 }
182 };
183 executor->PostTask(task, TaskExecutor::TaskType::UI, "ArkUIDialogCloseCustomDialog");
184 }
185
SetCloseDialogForNDK(FrameNode * dialogNode)186 void CustomDialogControllerModelNG::SetCloseDialogForNDK(FrameNode* dialogNode)
187 {
188 CHECK_NULL_VOID(dialogNode);
189 ContainerScope scope(Container::CurrentIdSafely());
190 auto container = Container::Current();
191 dialogNode->SetIsUseTransitionAnimator(true);
192 auto dialogRef = AceType::Claim(dialogNode);
193 CHECK_NULL_VOID(container);
194 auto pipelineContext = container->GetPipelineContext();
195 CHECK_NULL_VOID(pipelineContext);
196 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
197 CHECK_NULL_VOID(context);
198 auto overlayManager = context->GetOverlayManager();
199 CHECK_NULL_VOID(overlayManager);
200 auto currentOverlay = DialogManager::GetInstance().GetEmbeddedOverlayWithNode(dialogRef);
201 if (currentOverlay) {
202 overlayManager = currentOverlay;
203 }
204 overlayManager->CloseDialog(dialogRef);
205 }
206 } // namespace OHOS::Ace::NG
207