• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 
17 #include "base/error/error_code.h"
18 #include "core/common/container.h"
19 #include "core/components_ng/pattern/navrouter/navdestination_pattern.h"
20 #include "core/components_ng/pattern/overlay/dialog_manager.h"
21 #include "core/components_ng/pattern/overlay/sheet_manager.h"
22 #include "core/components_ng/pattern/stage/page_pattern.h"
23 #include "core/common/ace_engine.h"
24 #include "base/memory/ace_type.h"
25 #include "base/subwindow/subwindow_manager.h"
26 
27 namespace OHOS::Ace::NG {
28 namespace {
29 } // namespace
30 
31 DialogManager::DialogManager() = default;
32 
33 DialogManager::~DialogManager() = default;
34 
ShowInEmbeddedOverlay(std::function<void (RefPtr<NG::OverlayManager>)> && task,const std::string & name,int32_t uniqueId)35 void DialogManager::ShowInEmbeddedOverlay(std::function<void(RefPtr<NG::OverlayManager>)>&& task,
36     const std::string& name, int32_t uniqueId)
37 {
38     auto currentId = Container::CurrentId();
39     ContainerScope scope(currentId);
40     auto context = NG::PipelineContext::GetCurrentContext();
41     CHECK_NULL_VOID(context);
42     auto overlayManager = context->GetOverlayManager();
43     auto embeddedOverlay = GetEmbeddedOverlay(uniqueId, context);
44     if (embeddedOverlay) {
45         overlayManager = embeddedOverlay;
46     }
47     context->GetTaskExecutor()->PostTask(
48         [task = std::move(task), weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
49             auto overlayManager = weak.Upgrade();
50             task(overlayManager);
51         },
52         TaskExecutor::TaskType::UI, name);
53 }
54 
FindPageNodeOverlay(const RefPtr<FrameNode> & currentNode)55 RefPtr<OverlayManager> DialogManager::FindPageNodeOverlay(const RefPtr<FrameNode>& currentNode)
56 {
57     if (currentNode == nullptr || !currentNode->IsOnMainTree()) {
58         TAG_LOGE(AceLogTag::ACE_DIALOG, "dialog node does not exist or not on main tree.");
59     } else {
60         return SheetManager::FindPageNodeOverlay(currentNode, true, true);
61     }
62     return nullptr;
63 }
64 
GetEmbeddedOverlay(int32_t uniqueId,const RefPtr<PipelineContext> & context)65 RefPtr<OverlayManager> DialogManager::GetEmbeddedOverlay(int32_t uniqueId, const RefPtr<PipelineContext>& context)
66 {
67     CHECK_NULL_RETURN(context, nullptr);
68     if (uniqueId >= 0) {
69         auto currentNode = ElementRegister::GetInstance()->GetSpecificItemById<NG::FrameNode>(uniqueId);
70         if (currentNode == nullptr || !currentNode->IsOnMainTree()) {
71             TAG_LOGE(AceLogTag::ACE_DIALOG, "Level uniqueId/%{public}d does not exist or not on main tree.", uniqueId);
72         } else {
73             auto getOverlayManager = FindPageNodeOverlay(currentNode);
74             if (getOverlayManager) {
75                 return getOverlayManager;
76             } else {
77                 TAG_LOGE(AceLogTag::ACE_DIALOG, "Level uniqueId/%{public}d can not get overlay manager.", uniqueId);
78             }
79         }
80     } else {
81         auto stateMgr = context->GetStageManager();
82         if (stateMgr && stateMgr->GetLastPage()) {
83             auto pagePattern = stateMgr->GetLastPage()->GetPattern<NG::PagePattern>();
84             if (pagePattern) {
85                 pagePattern->CreateOverlayManager(true);
86                 return pagePattern->GetOverlayManager();
87             }
88         } else {
89             TAG_LOGE(AceLogTag::ACE_DIALOG, "Can not get current page");
90         }
91     }
92     return nullptr;
93 }
94 
GetEmbeddedOverlayWithNode(const RefPtr<UINode> & dialogNode)95 RefPtr<OverlayManager> DialogManager::GetEmbeddedOverlayWithNode(const RefPtr<UINode>& dialogNode)
96 {
97     CHECK_NULL_RETURN(dialogNode, nullptr);
98     auto parent = dialogNode->GetParent();
99     CHECK_NULL_RETURN(parent, nullptr);
100     auto parentNode = AceType::DynamicCast<FrameNode>(parent);
101     CHECK_NULL_RETURN(parentNode, nullptr);
102     if (parentNode->GetTag() == V2::PAGE_ETS_TAG) {
103         auto pattern = parentNode->GetPattern<PagePattern>();
104         CHECK_NULL_RETURN(pattern, nullptr);
105         return pattern->GetOverlayManager();
106     } else if (parentNode->GetTag() == V2::NAVDESTINATION_VIEW_ETS_TAG) {
107         auto pattern = parentNode->GetPattern<NavDestinationPattern>();
108         CHECK_NULL_RETURN(pattern, nullptr);
109         return pattern->GetOverlayManager();
110     }
111     return nullptr;
112 }
113 
GetDialogNodeByContentNode(const RefPtr<UINode> & currentNode)114 RefPtr<UINode> DialogManager::GetDialogNodeByContentNode(const RefPtr<UINode>& currentNode)
115 {
116     RefPtr<UINode> parent = currentNode;
117     while (parent) {
118         if (parent->GetTag() == V2::DIALOG_ETS_TAG) {
119             break;
120         }
121         parent = parent->GetParent();
122     }
123     return parent;
124 }
125 
IsPcOrFreeMultiWindow(const RefPtr<FrameNode> & currentNode) const126 bool DialogManager::IsPcOrFreeMultiWindow(const RefPtr<FrameNode>& currentNode) const
127 {
128     auto pipelineContext = currentNode->GetContextRefPtr();
129     CHECK_NULL_RETURN(pipelineContext, false);
130     auto dialogTheme = pipelineContext->GetTheme<DialogTheme>();
131     CHECK_NULL_RETURN(dialogTheme, false);
132     auto expandDisplay = dialogTheme->GetExpandDisplay();
133     auto containerId = pipelineContext->GetInstanceId();
134     auto container = AceEngine::Get().GetContainer(containerId);
135     CHECK_NULL_RETURN(container, false);
136     auto isFreeMultiWindow = container->IsFreeMultiWindow();
137     return expandDisplay || isFreeMultiWindow;
138 }
139 
GetMainPipelineContext(const RefPtr<FrameNode> & frameNode,bool isTargetNodeInSubwindow)140 RefPtr<PipelineContext> DialogManager::GetMainPipelineContext(
141     const RefPtr<FrameNode>& frameNode, bool isTargetNodeInSubwindow)
142 {
143     // Get pipelineContext of main window or host window for UIExtension
144     if (!frameNode) {
145         TAG_LOGE(AceLogTag::ACE_OVERLAY, "get frameNode failed");
146         return nullptr;
147     }
148     auto pipeline = frameNode->GetContext();
149     if (!pipeline) {
150         TAG_LOGE(AceLogTag::ACE_OVERLAY, "get pipeline failed, nodeId: %{public}d", frameNode->GetId());
151         return nullptr;
152     }
153     auto containerId = pipeline->GetInstanceId();
154     auto container = AceEngine::Get().GetContainer(containerId);
155     if (!container) {
156         TAG_LOGE(AceLogTag::ACE_OVERLAY, "get container failed, nodeId: %{public}d", frameNode->GetId());
157         return nullptr;
158     }
159     RefPtr<PipelineContext> context;
160     if (container->IsSubContainer() && !isTargetNodeInSubwindow) {
161         auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(containerId);
162         auto parentContainer = AceEngine::Get().GetContainer(parentContainerId);
163         if (!parentContainer) {
164             TAG_LOGE(AceLogTag::ACE_OVERLAY, "get parentContainer failed, nodeId: %{public}d", frameNode->GetId());
165             return nullptr;
166         }
167         context = AceType::DynamicCast<PipelineContext>(parentContainer->GetPipelineContext());
168         if (!context) {
169             TAG_LOGE(AceLogTag::ACE_OVERLAY, "get context failed, nodeId: %{public}d", frameNode->GetId());
170             return nullptr;
171         }
172     } else {
173         context = AceType::Claim(pipeline);
174     }
175     return context;
176 }
177 } // namespace OHOS::Ace::NG
178