1 /*
2 * Copyright (c) 2022-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
16 #include "base/subwindow/subwindow_manager.h"
17
18 #include "core/pipeline_ng/pipeline_context.h"
19 #include "core/components/select/select_theme.h"
20
21 namespace OHOS::Ace {
22 namespace {
23 constexpr uint64_t DEFAULT_DISPLAY_ID = 0;
24 constexpr uint64_t VIRTUAL_DISPLAY_ID = 999;
25 } // namespace
26 std::mutex SubwindowManager::instanceMutex_;
27 std::shared_ptr<SubwindowManager> SubwindowManager::instance_;
28 thread_local RefPtr<Subwindow> SubwindowManager::currentSubwindow_;
29 const std::unordered_set<SubwindowType> NORMAL_SUBWINDOW_TYPE = { SubwindowType::TYPE_MENU,
30 SubwindowType::TYPE_DIALOG, SubwindowType::TYPE_POPUP };
31
GetInstance()32 std::shared_ptr<SubwindowManager> SubwindowManager::GetInstance()
33 {
34 std::lock_guard<std::mutex> lock(instanceMutex_);
35 if (!instance_) {
36 instance_ = std::make_shared<SubwindowManager>();
37 if (instance_) {
38 instance_->isSuperFoldDisplayDevice_ = SystemProperties::IsSuperFoldDisplayDevice();
39 }
40 }
41 return instance_;
42 }
43
AddContainerId(uint32_t windowId,int32_t containerId)44 void SubwindowManager::AddContainerId(uint32_t windowId, int32_t containerId)
45 {
46 std::lock_guard<std::mutex> lock(mutex_);
47 auto result = containerMap_.find(windowId);
48 if (result != containerMap_.end()) {
49 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Already have container of this windowId, windowId: %{public}u", windowId);
50 }
51 containerMap_.emplace(windowId, containerId);
52 }
53
RemoveContainerId(uint32_t windowId)54 void SubwindowManager::RemoveContainerId(uint32_t windowId)
55 {
56 std::lock_guard<std::mutex> lock(mutex_);
57 containerMap_.erase(windowId);
58 }
59
GetContainerId(uint32_t windowId)60 int32_t SubwindowManager::GetContainerId(uint32_t windowId)
61 {
62 std::lock_guard<std::mutex> lock(mutex_);
63 auto result = containerMap_.find(windowId);
64 if (result != containerMap_.end()) {
65 return result->second;
66 } else {
67 return -1;
68 }
69 }
70
AddParentContainerId(int32_t containerId,int32_t parentContainerId)71 void SubwindowManager::AddParentContainerId(int32_t containerId, int32_t parentContainerId)
72 {
73 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Container id is %{public}d, parent id is %{public}d.", containerId,
74 parentContainerId);
75 std::lock_guard<std::mutex> lock(parentMutex_);
76 parentContainerMap_.try_emplace(containerId, parentContainerId);
77 }
78
RemoveParentContainerId(int32_t containerId)79 void SubwindowManager::RemoveParentContainerId(int32_t containerId)
80 {
81 std::lock_guard<std::mutex> lock(parentMutex_);
82 parentContainerMap_.erase(containerId);
83 }
84
GetParentContainerId(int32_t containerId)85 int32_t SubwindowManager::GetParentContainerId(int32_t containerId)
86 {
87 std::lock_guard<std::mutex> lock(parentMutex_);
88 auto result = parentContainerMap_.find(containerId);
89 if (result != parentContainerMap_.end()) {
90 return result->second;
91 } else {
92 return -1;
93 }
94 }
95
GetSubContainerId(int32_t parentContainerId)96 int32_t SubwindowManager::GetSubContainerId(int32_t parentContainerId)
97 {
98 std::lock_guard<std::mutex> lock(parentMutex_);
99 for (auto it = parentContainerMap_.begin(); it != parentContainerMap_.end(); it++) {
100 if (it->second == parentContainerId) {
101 return it->first;
102 }
103 }
104 return -1;
105 }
106
GetAllSubContainerId(int32_t parentContainerId)107 const std::vector<int32_t> SubwindowManager::GetAllSubContainerId(int32_t parentContainerId)
108 {
109 std::lock_guard<std::mutex> lock(parentMutex_);
110 std::vector<int32_t> subContainerId;
111 subContainerId.reserve(parentContainerMap_.size());
112 for (auto it = parentContainerMap_.begin(); it != parentContainerMap_.end(); it++) {
113 if (it->second == parentContainerId) {
114 subContainerId.push_back(it->first);
115 }
116 }
117
118 return subContainerId;
119 }
120
AddInstanceSubwindowMap(int32_t subInstanceId,RefPtr<Subwindow> subwindow)121 void SubwindowManager::AddInstanceSubwindowMap(int32_t subInstanceId, RefPtr<Subwindow> subwindow)
122 {
123 if (!subwindow) {
124 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add instance subwindow map failed.");
125 return;
126 }
127
128 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
129 "add subwindow into map, subInstanceId is %{public}d, subwindow id is %{public}d.", subInstanceId,
130 subwindow->GetSubwindowId());
131
132 std::lock_guard<std::mutex> lock(instanceSubwindowMutex_);
133 auto result = instanceSubwindowMap_.try_emplace(subInstanceId, subwindow);
134 if (!result.second) {
135 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add failed of this subInstance %{public}d", subInstanceId);
136 return;
137 }
138 }
139
OnDestroyContainer(int32_t subInstanceId)140 void SubwindowManager::OnDestroyContainer(int32_t subInstanceId)
141 {
142 if (subInstanceId < MIN_SUBCONTAINER_ID) {
143 return;
144 }
145
146 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "remove subwindow from map, subInstanceId is %{public}d", subInstanceId);
147 RemoveParentContainerId(subInstanceId);
148 std::lock_guard<std::mutex> lock(instanceSubwindowMutex_);
149 instanceSubwindowMap_.erase(subInstanceId);
150 }
151
AddSubwindow(int32_t instanceId,RefPtr<Subwindow> subwindow)152 void SubwindowManager::AddSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
153 {
154 AddSubwindow(instanceId, SubwindowType::TYPE_DIALOG, subwindow);
155 }
156
AddToastSubwindow(int32_t instanceId,RefPtr<Subwindow> subwindow)157 void SubwindowManager::AddToastSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
158 {
159 AddSubwindow(instanceId, SubwindowType::TYPE_TOP_MOST_TOAST, subwindow);
160 }
161
AddSystemToastWindow(int32_t instanceId,RefPtr<Subwindow> subwindow)162 void SubwindowManager::AddSystemToastWindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
163 {
164 AddSubwindow(instanceId, SubwindowType::TYPE_SYSTEM_TOP_MOST_TOAST, subwindow);
165 }
166
DeleteHotAreas(int32_t instanceId,int32_t nodeId,SubwindowType type)167 void SubwindowManager::DeleteHotAreas(int32_t instanceId, int32_t nodeId, SubwindowType type)
168 {
169 RefPtr<Subwindow> subwindow;
170 if (instanceId != -1) {
171 // get the subwindow which overlay node in, not current
172 subwindow = GetSubwindowByType(instanceId, type);
173 } else {
174 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to get the subwindow which overlay node in, so get the current one.");
175 subwindow = GetCurrentWindow();
176 }
177 if (subwindow) {
178 subwindow->DeleteHotAreas(nodeId);
179 }
180 }
181
RemoveSubwindow(int32_t instanceId,SubwindowType windowType)182 void SubwindowManager::RemoveSubwindow(int32_t instanceId, SubwindowType windowType)
183 {
184 SubwindowKey searchKey = GetCurrentSubwindowKey(instanceId, windowType);
185 std::lock_guard<std::mutex> lock(subwindowMutex_);
186 subwindowMap_.erase(searchKey);
187 }
188
GetSubwindow(int32_t instanceId)189 const RefPtr<Subwindow> SubwindowManager::GetSubwindow(int32_t instanceId)
190 {
191 return GetSubwindowByType(instanceId, SubwindowType::TYPE_DIALOG);
192 }
193
GetSubwindowById(int32_t subinstanceId)194 const RefPtr<Subwindow> SubwindowManager::GetSubwindowById(int32_t subinstanceId)
195 {
196 std::lock_guard<std::mutex> lock(instanceSubwindowMutex_);
197 auto result = instanceSubwindowMap_.find(subinstanceId);
198 if (result != instanceSubwindowMap_.end()) {
199 return result->second;
200 }
201
202 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to find subwindow in instanceSubwindowMap_, subinstanceId is %{public}d",
203 subinstanceId);
204 return nullptr;
205 }
206
GetToastSubwindow(int32_t instanceId)207 const RefPtr<Subwindow> SubwindowManager::GetToastSubwindow(int32_t instanceId)
208 {
209 return GetSubwindowByType(instanceId, SubwindowType::TYPE_TOP_MOST_TOAST);
210 }
211
GetSystemToastWindow(int32_t instanceId)212 const RefPtr<Subwindow> SubwindowManager::GetSystemToastWindow(int32_t instanceId)
213 {
214 return GetSubwindowByType(instanceId, SubwindowType::TYPE_SYSTEM_TOP_MOST_TOAST);
215 }
216
GetDialogSubwindowInstanceId(int32_t SubwindowId)217 int32_t SubwindowManager::GetDialogSubwindowInstanceId(int32_t SubwindowId)
218 {
219 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get dialog subwindow instanceid enter");
220 std::lock_guard<std::mutex> lock(subwindowMutex_);
221 for (auto it = subwindowMap_.begin(); it != subwindowMap_.end(); it++) {
222 if (it->second->GetSubwindowId() == SubwindowId) {
223 return (it->first).instanceId;
224 }
225 }
226 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to get parentContainerId of subwindow in subwindowMap_,"
227 "subwindowId is %{public}d.", SubwindowId);
228 return 0;
229 }
230
SetCurrentSubwindow(const RefPtr<Subwindow> & subwindow)231 void SubwindowManager::SetCurrentSubwindow(const RefPtr<Subwindow>& subwindow)
232 {
233 currentSubwindow_ = subwindow;
234 }
235
GetCurrentWindow()236 const RefPtr<Subwindow> SubwindowManager::GetCurrentWindow()
237 {
238 auto containerId = Container::CurrentId();
239 if (containerId >= MIN_SUBCONTAINER_ID) {
240 return SubwindowManager::GetInstance()->GetSubwindowById(containerId);
241 }
242 return currentSubwindow_;
243 }
244
GetParentWindowRect()245 Rect SubwindowManager::GetParentWindowRect()
246 {
247 Rect rect;
248 CHECK_NULL_RETURN(currentSubwindow_, rect);
249 return currentSubwindow_->GetParentWindowRect();
250 }
251
ShowPreviewNG(bool isStartDraggingFromSubWindow)252 RefPtr<Subwindow> SubwindowManager::ShowPreviewNG(bool isStartDraggingFromSubWindow)
253 {
254 auto containerId = Container::CurrentId();
255 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_MENU);
256 if (!IsSubwindowExist(subwindow)) {
257 subwindow = Subwindow::CreateSubwindow(containerId);
258 subwindow->InitContainer();
259 CHECK_NULL_RETURN(subwindow->GetIsRosenWindowCreate(), nullptr);
260 AddSubwindow(containerId, SubwindowType::TYPE_MENU, subwindow);
261 }
262 if (!subwindow->ShowPreviewNG(isStartDraggingFromSubWindow)) {
263 return nullptr;
264 }
265 return subwindow;
266 }
267
ShowMenuNG(const RefPtr<NG::FrameNode> & menuNode,const NG::MenuParam & menuParam,const RefPtr<NG::FrameNode> & targetNode,const NG::OffsetF & offset)268 void SubwindowManager::ShowMenuNG(const RefPtr<NG::FrameNode>& menuNode, const NG::MenuParam& menuParam,
269 const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
270 {
271 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
272 CHECK_NULL_VOID(targetNode);
273 auto pipelineContext = targetNode->GetContext();
274 CHECK_NULL_VOID(pipelineContext);
275 auto containerId = pipelineContext->GetInstanceId();
276 if (containerId >= MIN_SUBCONTAINER_ID) {
277 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "subwindow can not show menu again");
278 return;
279 }
280 auto subwindow = GetOrCreateMenuSubWindow(containerId);
281 CHECK_NULL_VOID(subwindow);
282 subwindow->ShowMenuNG(menuNode, menuParam, targetNode, offset);
283 }
284
ShowMenuNG(std::function<void ()> && buildFunc,std::function<void ()> && previewBuildFunc,const NG::MenuParam & menuParam,const RefPtr<NG::FrameNode> & targetNode,const NG::OffsetF & offset)285 void SubwindowManager::ShowMenuNG(std::function<void()>&& buildFunc, std::function<void()>&& previewBuildFunc,
286 const NG::MenuParam& menuParam, const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
287 {
288 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
289 CHECK_NULL_VOID(targetNode);
290 auto pipelineContext = targetNode->GetContext();
291 CHECK_NULL_VOID(pipelineContext);
292 auto containerId = pipelineContext->GetInstanceId();
293 if (containerId >= MIN_SUBCONTAINER_ID) {
294 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "subwindow can not show menu again");
295 return;
296 }
297 auto subwindow = GetOrCreateMenuSubWindow(containerId);
298 CHECK_NULL_VOID(subwindow);
299 subwindow->ShowMenuNG(std::move(buildFunc), std::move(previewBuildFunc), menuParam, targetNode, offset);
300 }
301
HidePreviewNG()302 void SubwindowManager::HidePreviewNG()
303 {
304 auto subwindow = GetCurrentWindow();
305 if (subwindow) {
306 subwindow->HidePreviewNG();
307 }
308 }
309
HideMenuNG(const RefPtr<NG::FrameNode> & menu,int32_t targetId)310 void SubwindowManager::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)
311 {
312 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
313 auto subwindow = GetCurrentWindow();
314 if (subwindow) {
315 subwindow->HideMenuNG(menu, targetId);
316 }
317 }
318
HideMenuNG(bool showPreviewAnimation,bool startDrag)319 void SubwindowManager::HideMenuNG(bool showPreviewAnimation, bool startDrag)
320 {
321 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
322 auto subwindow = GetCurrentWindow();
323 if (subwindow) {
324 subwindow->HideMenuNG(showPreviewAnimation, startDrag);
325 }
326 }
327
UpdateHideMenuOffsetNG(const NG::OffsetF & offset,float menuScale,bool isRedragStart,int32_t menuWrapperId)328 void SubwindowManager::UpdateHideMenuOffsetNG(
329 const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)
330 {
331 auto subwindow = GetCurrentWindow();
332 if (subwindow) {
333 subwindow->UpdateHideMenuOffsetNG(offset, menuScale, isRedragStart, menuWrapperId);
334 }
335 }
336
ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode> & dragPreviewNode,const NG::OffsetF & offset)337 void SubwindowManager::ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode>& dragPreviewNode,
338 const NG::OffsetF& offset)
339 {
340 CHECK_NULL_VOID(dragPreviewNode);
341 auto subwindow = GetCurrentWindow();
342 if (subwindow) {
343 subwindow->ContextMenuSwitchDragPreviewAnimationtNG(dragPreviewNode, offset);
344 }
345 }
346
UpdatePreviewPosition()347 void SubwindowManager::UpdatePreviewPosition()
348 {
349 auto subwindow = GetCurrentWindow();
350 if (subwindow) {
351 subwindow->UpdatePreviewPosition();
352 }
353 }
354
GetMenuPreviewCenter(NG::OffsetF & offset)355 bool SubwindowManager::GetMenuPreviewCenter(NG::OffsetF& offset)
356 {
357 auto subwindow = GetCurrentWindow();
358 if (subwindow) {
359 return subwindow->GetMenuPreviewCenter(offset);
360 }
361 return false;
362 }
363
ClearMenuNG(int32_t instanceId,int32_t targetId,bool inWindow,bool showAnimation)364 void SubwindowManager::ClearMenuNG(int32_t instanceId, int32_t targetId, bool inWindow, bool showAnimation)
365 {
366 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear menu ng enter");
367 RefPtr<Subwindow> subwindow;
368 if (instanceId != -1) {
369 #ifdef OHOS_STANDARD_SYSTEM
370 // get the subwindow which overlay node in, not current
371 subwindow = GetSubwindowByType(instanceId, SubwindowType::TYPE_MENU);
372 #else
373 subwindow = GetSubwindowByType(GetParentContainerId(instanceId) != -1 ?
374 GetParentContainerId(instanceId) : instanceId, SubwindowType::TYPE_MENU);
375 #endif
376 } else {
377 subwindow = GetCurrentWindow();
378 }
379 if (subwindow) {
380 subwindow->ClearMenuNG(targetId, inWindow, showAnimation);
381 }
382 }
383
ClearPopupInSubwindow(int32_t instanceId,bool isForceClear)384 void SubwindowManager::ClearPopupInSubwindow(int32_t instanceId, bool isForceClear)
385 {
386 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear popup in subwindow enter");
387 RefPtr<Subwindow> subwindow;
388 if (instanceId != -1) {
389 // get the subwindow which overlay node in, not current
390 subwindow = GetSubwindowByType(instanceId, SubwindowType::TYPE_POPUP);
391 } else {
392 subwindow = GetCurrentWindow();
393 }
394 if (subwindow) {
395 subwindow->ClearPopupNG(isForceClear);
396 }
397 }
398
ShowPopupNG(const RefPtr<NG::FrameNode> & targetNode,const NG::PopupInfo & popupInfo,const std::function<void (int32_t)> && onWillDismiss,bool interactiveDismiss)399 void SubwindowManager::ShowPopupNG(const RefPtr<NG::FrameNode>& targetNode, const NG::PopupInfo& popupInfo,
400 const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
401 {
402 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show popup ng enter");
403 CHECK_NULL_VOID(targetNode);
404 auto pipelineContext = targetNode->GetContext();
405 CHECK_NULL_VOID(pipelineContext);
406 auto containerId = pipelineContext->GetInstanceId();
407 if (containerId >= MIN_SUBCONTAINER_ID && !GetIsExpandDisplay()) {
408 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "subwindow can not show popup ng again");
409 return;
410 }
411
412 auto manager = SubwindowManager::GetInstance();
413 CHECK_NULL_VOID(manager);
414 auto subwindow = manager->GetSubwindowByType(containerId, SubwindowType::TYPE_POPUP);
415 if (!IsSubwindowExist(subwindow)) {
416 subwindow = Subwindow::CreateSubwindow(containerId);
417 subwindow->InitContainer();
418 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
419 manager->AddSubwindow(containerId, SubwindowType::TYPE_POPUP, subwindow);
420 }
421 subwindow->ShowPopupNG(targetNode->GetId(), popupInfo, std::move(onWillDismiss), interactiveDismiss);
422 }
423
HidePopupNG(int32_t targetId,int32_t instanceId)424 void SubwindowManager::HidePopupNG(int32_t targetId, int32_t instanceId)
425 {
426 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "hide popup ng enter");
427 RefPtr<Subwindow> subwindow;
428 if (instanceId != -1) {
429 // get the subwindow which overlay node in, not current
430 subwindow = GetSubwindowByType(instanceId, SubwindowType::TYPE_POPUP);
431 } else {
432 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to get the subwindow which overlay node in, so get the current one.");
433 subwindow = GetCurrentWindow();
434 }
435
436 if (subwindow) {
437 subwindow->HidePopupNG(targetId);
438 }
439 }
440
ShowPopup(const RefPtr<Component> & newComponent,bool disableTouchEvent)441 void SubwindowManager::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
442 {
443 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show popup enter");
444 auto containerId = Container::CurrentId();
445 if (containerId >= MIN_SUBCONTAINER_ID && !GetIsExpandDisplay()) {
446 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "subwindow can not show popup again");
447 return;
448 }
449 auto taskExecutor = Container::CurrentTaskExecutor();
450 CHECK_NULL_VOID(taskExecutor);
451 taskExecutor->PostTask(
452 [containerId, newComponentWeak = WeakPtr<Component>(newComponent), disableTouchEvent] {
453 auto manager = SubwindowManager::GetInstance();
454 CHECK_NULL_VOID(manager);
455 auto subwindow = manager->GetSubwindowByType(containerId, SubwindowType::TYPE_POPUP);
456 if (!manager->IsSubwindowExist(subwindow)) {
457 subwindow = Subwindow::CreateSubwindow(containerId);
458 subwindow->InitContainer();
459 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
460 manager->AddSubwindow(containerId, SubwindowType::TYPE_POPUP, subwindow);
461 }
462 auto newComponent = newComponentWeak.Upgrade();
463 CHECK_NULL_VOID(newComponent);
464 subwindow->ShowPopup(newComponent, disableTouchEvent);
465 },
466 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowPopup");
467 }
468
ShowTipsNG(const RefPtr<NG::FrameNode> & targetNode,const NG::PopupInfo & popupInfo,int32_t appearingTime,int32_t appearingTimeWithContinuousOperation)469 void SubwindowManager::ShowTipsNG(const RefPtr<NG::FrameNode>& targetNode, const NG::PopupInfo& popupInfo,
470 int32_t appearingTime, int32_t appearingTimeWithContinuousOperation)
471 {
472 CHECK_NULL_VOID(targetNode);
473 auto pipelineContext = targetNode->GetContext();
474 CHECK_NULL_VOID(pipelineContext);
475 auto containerId = pipelineContext->GetInstanceId();
476
477 auto manager = SubwindowManager::GetInstance();
478 CHECK_NULL_VOID(manager);
479 auto subwindow = manager->GetSubwindow(containerId);
480 if (!IsSubwindowExist(subwindow)) {
481 subwindow = Subwindow::CreateSubwindow(containerId);
482 subwindow->InitContainer();
483 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
484 manager->AddSubwindow(containerId, subwindow);
485 }
486 subwindow->ShowTipsNG(targetNode->GetId(), popupInfo, appearingTime, appearingTimeWithContinuousOperation);
487 }
488
HideTipsNG(int32_t targetId,int32_t disappearingTime,int32_t instanceId)489 void SubwindowManager::HideTipsNG(int32_t targetId, int32_t disappearingTime, int32_t instanceId)
490 {
491 RefPtr<Subwindow> subwindow;
492 if (instanceId != -1) {
493 // get the subwindow which overlay node in, not current
494 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
495 } else {
496 subwindow = GetCurrentWindow();
497 }
498 if (subwindow) {
499 subwindow->HideTipsNG(targetId, disappearingTime);
500 }
501 }
502
CancelPopup(const std::string & id)503 bool SubwindowManager::CancelPopup(const std::string& id)
504 {
505 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "cancel popup enter");
506 auto subwindow = GetCurrentWindow();
507 if (subwindow) {
508 return subwindow->CancelPopup(id);
509 }
510 return false;
511 }
512
ShowMenu(const RefPtr<Component> & newComponent)513 void SubwindowManager::ShowMenu(const RefPtr<Component>& newComponent)
514 {
515 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show menu enter");
516 auto containerId = Container::CurrentId();
517 auto taskExecutor = Container::CurrentTaskExecutor();
518 CHECK_NULL_VOID(taskExecutor);
519 taskExecutor->PostTask(
520 [containerId, weakMenu = AceType::WeakClaim(AceType::RawPtr(newComponent))] {
521 auto manager = SubwindowManager::GetInstance();
522 CHECK_NULL_VOID(manager);
523 auto menu = weakMenu.Upgrade();
524 CHECK_NULL_VOID(menu);
525 auto subwindow = manager->GetOrCreateMenuSubWindow(containerId);
526 CHECK_NULL_VOID(subwindow);
527 subwindow->ShowMenu(menu);
528 },
529 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowMenu");
530 }
531
CloseMenu()532 void SubwindowManager::CloseMenu()
533 {
534 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close menu enter");
535 auto subwindow = GetCurrentWindow();
536 if (subwindow) {
537 subwindow->CloseMenu();
538 }
539 }
540
ClearMenu()541 void SubwindowManager::ClearMenu()
542 {
543 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear menu enter");
544 auto subwindow = GetCurrentWindow();
545 if (subwindow) {
546 subwindow->ClearMenu();
547 }
548 }
549
SetHotAreas(const std::vector<Rect> & rects,SubwindowType type,int32_t nodeId,int32_t instanceId)550 void SubwindowManager::SetHotAreas(
551 const std::vector<Rect>& rects, SubwindowType type, int32_t nodeId, int32_t instanceId)
552 {
553 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set hot areas enter");
554 RefPtr<Subwindow> subwindow;
555 if (instanceId != -1) {
556 // get the subwindow which overlay node in, not current
557 subwindow = GetSubwindowByType(instanceId, type);
558 } else {
559 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to get the subwindow which overlay node in, so get the current one.");
560 subwindow = GetCurrentWindow();
561 }
562
563 if (subwindow) {
564 subwindow->SetHotAreas(rects, nodeId);
565 }
566 }
567
ShowBindSheetNG(bool isShow,std::function<void (const std::string &)> && callback,std::function<RefPtr<NG::UINode> ()> && buildNodeFunc,std::function<RefPtr<NG::UINode> ()> && buildtitleNodeFunc,NG::SheetStyle & sheetStyle,std::function<void ()> && onAppear,std::function<void ()> && onDisappear,std::function<void ()> && shouldDismiss,std::function<void (const int32_t)> && onWillDismiss,std::function<void ()> && onWillAppear,std::function<void ()> && onWillDisappear,std::function<void (const float)> && onHeightDidChange,std::function<void (const float)> && onDetentsDidChange,std::function<void (const float)> && onWidthDidChange,std::function<void (const float)> && onTypeDidChange,std::function<void ()> && sheetSpringBack,const RefPtr<NG::FrameNode> & targetNode)568 void SubwindowManager::ShowBindSheetNG(bool isShow, std::function<void(const std::string&)>&& callback,
569 std::function<RefPtr<NG::UINode>()>&& buildNodeFunc, std::function<RefPtr<NG::UINode>()>&& buildtitleNodeFunc,
570 NG::SheetStyle& sheetStyle, std::function<void()>&& onAppear, std::function<void()>&& onDisappear,
571 std::function<void()>&& shouldDismiss, std::function<void(const int32_t)>&& onWillDismiss,
572 std::function<void()>&& onWillAppear, std::function<void()>&& onWillDisappear,
573 std::function<void(const float)>&& onHeightDidChange,
574 std::function<void(const float)>&& onDetentsDidChange,
575 std::function<void(const float)>&& onWidthDidChange,
576 std::function<void(const float)>&& onTypeDidChange,
577 std::function<void()>&& sheetSpringBack, const RefPtr<NG::FrameNode>& targetNode)
578 {
579 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show sheet ng enter");
580 auto containerId = Container::CurrentId();
581 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_SHEET);
582 if (!IsSubwindowExist(subwindow)) {
583 subwindow = Subwindow::CreateSubwindow(containerId);
584 CHECK_NULL_VOID(subwindow);
585 CHECK_NULL_VOID(subwindow->CheckHostWindowStatus());
586 subwindow->InitContainer();
587 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
588 AddSubwindow(containerId, SubwindowType::TYPE_SHEET, subwindow);
589 }
590 return subwindow->ShowBindSheetNG(isShow, std::move(callback), std::move(buildNodeFunc),
591 std::move(buildtitleNodeFunc), sheetStyle, std::move(onAppear), std::move(onDisappear),
592 std::move(shouldDismiss), std::move(onWillDismiss),
593 std::move(onWillAppear), std::move(onWillDisappear), std::move(onHeightDidChange),
594 std::move(onDetentsDidChange), std::move(onWidthDidChange), std::move(onTypeDidChange),
595 std::move(sheetSpringBack), targetNode);
596 }
597
OnWindowSizeChanged(int32_t containerId,Rect windowRect,WindowSizeChangeReason reason)598 void SubwindowManager::OnWindowSizeChanged(int32_t containerId, Rect windowRect, WindowSizeChangeReason reason)
599 {
600 OnUIExtensionWindowSizeChange(containerId, windowRect, reason);
601 OnHostWindowSizeChanged(containerId, windowRect, reason);
602 }
603
OnHostWindowSizeChanged(int32_t containerId,Rect windowRect,WindowSizeChangeReason reason)604 void SubwindowManager::OnHostWindowSizeChanged(int32_t containerId, Rect windowRect, WindowSizeChangeReason reason)
605 {
606 auto container = Container::GetContainer(containerId);
607 CHECK_NULL_VOID(container);
608 auto subContinerId = GetSubContainerId(containerId);
609 auto subContainer = Container::GetContainer(subContinerId);
610 CHECK_NULL_VOID(subContainer);
611 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(subContainer->GetPipelineContext());
612 CHECK_NULL_VOID(pipeline);
613 auto overlayManager = pipeline->GetOverlayManager();
614 CHECK_NULL_VOID(overlayManager);
615 overlayManager->OnMainWindowSizeChange(subContinerId);
616 }
617
HideSheetSubWindow(int32_t containerId)618 void SubwindowManager::HideSheetSubWindow(int32_t containerId)
619 {
620 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide sheet subwindow enter %u", containerId);
621 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_SHEET);
622 CHECK_NULL_VOID(subwindow);
623 auto overlay = subwindow->GetOverlayManager();
624 CHECK_NULL_VOID(overlay);
625 if (overlay->GetSheetMap().empty()) {
626 subwindow->HideSubWindowNG();
627 return;
628 }
629 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "fail to hide sheet subwindow, instanceId is %{public}d.", containerId);
630 }
631
ShowDialogNG(const DialogProperties & dialogProps,std::function<void ()> && buildFunc)632 RefPtr<NG::FrameNode> SubwindowManager::ShowDialogNG(
633 const DialogProperties& dialogProps, std::function<void()>&& buildFunc)
634 {
635 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
636 auto containerId = Container::CurrentId();
637 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
638 if (!IsSubwindowExist(subwindow)) {
639 subwindow = Subwindow::CreateSubwindow(containerId);
640 CHECK_NULL_RETURN(subwindow, nullptr);
641 CHECK_NULL_RETURN(subwindow->CheckHostWindowStatus(), nullptr);
642 subwindow->InitContainer();
643 CHECK_NULL_RETURN(subwindow->GetIsRosenWindowCreate(), nullptr);
644 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
645 }
646 return subwindow->ShowDialogNG(dialogProps, std::move(buildFunc));
647 }
ShowDialogNGWithNode(const DialogProperties & dialogProps,const RefPtr<NG::UINode> & customNode)648 RefPtr<NG::FrameNode> SubwindowManager::ShowDialogNGWithNode(const DialogProperties& dialogProps,
649 const RefPtr<NG::UINode>& customNode)
650 {
651 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
652 auto containerId = Container::CurrentId();
653 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
654 if (!IsSubwindowExist(subwindow)) {
655 subwindow = Subwindow::CreateSubwindow(containerId);
656 CHECK_NULL_RETURN(subwindow, nullptr);
657 CHECK_NULL_RETURN(subwindow->CheckHostWindowStatus(), nullptr);
658 subwindow->InitContainer();
659 CHECK_NULL_RETURN(subwindow->GetIsRosenWindowCreate(), nullptr);
660 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
661 }
662 return subwindow->ShowDialogNGWithNode(dialogProps, customNode);
663 }
CloseDialogNG(const RefPtr<NG::FrameNode> & dialogNode)664 void SubwindowManager::CloseDialogNG(const RefPtr<NG::FrameNode>& dialogNode)
665 {
666 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close dialog ng enter");
667 CHECK_NULL_VOID(dialogNode);
668 auto containerId = Container::CurrentId();
669 auto pipeline = dialogNode->GetContextRefPtr();
670 if (pipeline) {
671 containerId = pipeline->GetInstanceId();
672 }
673 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
674 if (!subwindow) {
675 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get subwindow failed.");
676 return;
677 }
678 return subwindow->CloseDialogNG(dialogNode);
679 }
680
OpenCustomDialogNG(const DialogProperties & dialogProps,std::function<void (int32_t)> && callback)681 void SubwindowManager::OpenCustomDialogNG(const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)
682 {
683 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show customDialog ng enter");
684 auto containerId = Container::CurrentId();
685 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
686 if (!IsSubwindowExist(subwindow)) {
687 subwindow = Subwindow::CreateSubwindow(containerId);
688 CHECK_NULL_VOID(subwindow);
689 CHECK_NULL_VOID(subwindow->CheckHostWindowStatus());
690 subwindow->InitContainer();
691 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
692 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
693 }
694 return subwindow->OpenCustomDialogNG(dialogProps, std::move(callback));
695 }
696
CloseCustomDialogNG(int32_t dialogId)697 void SubwindowManager::CloseCustomDialogNG(int32_t dialogId)
698 {
699 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng enter");
700 for (auto &overlay : GetAllSubOverlayManager()) {
701 CHECK_NULL_VOID(overlay);
702 if (overlay->GetDialogMap().find(dialogId) != overlay->GetDialogMap().end()) {
703 return overlay->CloseCustomDialog(dialogId);
704 }
705 }
706 }
707
CloseCustomDialogNG(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)708 void SubwindowManager::CloseCustomDialogNG(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)
709 {
710 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng enter");
711 for (auto &overlay : GetAllSubOverlayManager()) {
712 CHECK_NULL_VOID(overlay);
713 overlay->CloseCustomDialog(node, std::move(callback));
714 }
715 }
716
UpdateCustomDialogNG(const WeakPtr<NG::UINode> & node,const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)717 void SubwindowManager::UpdateCustomDialogNG(
718 const WeakPtr<NG::UINode>& node, const PromptDialogAttr &dialogAttr, std::function<void(int32_t)>&& callback)
719 {
720 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "update customDialog ng enter");
721 DialogProperties dialogProperties = {
722 .autoCancel = dialogAttr.autoCancel,
723 .maskColor = dialogAttr.maskColor,
724 .isSysBlurStyle = false
725 };
726 if (dialogAttr.alignment.has_value()) {
727 dialogProperties.alignment = dialogAttr.alignment.value();
728 }
729 if (dialogAttr.offset.has_value()) {
730 dialogProperties.offset = dialogAttr.offset.value();
731 }
732 for (auto &overlay : GetAllSubOverlayManager()) {
733 if (overlay) {
734 overlay->UpdateCustomDialog(node, dialogProperties, std::move(callback));
735 }
736 }
737 }
738
GetTopOrder()739 std::optional<double> SubwindowManager::GetTopOrder()
740 {
741 auto containerId = Container::CurrentIdSafelyWithCheck();
742 auto container = Container::GetContainer(containerId);
743 CHECK_NULL_RETURN(container, std::nullopt);
744 auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
745 CHECK_NULL_RETURN(context, std::nullopt);
746 auto overlayManager = context->GetOverlayManager();
747 CHECK_NULL_RETURN(overlayManager, std::nullopt);
748 return overlayManager->GetTopOrder();
749 }
750
GetBottomOrder()751 std::optional<double> SubwindowManager::GetBottomOrder()
752 {
753 auto containerId = Container::CurrentIdSafelyWithCheck();
754 auto container = Container::GetContainer(containerId);
755 CHECK_NULL_RETURN(container, std::nullopt);
756 auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
757 CHECK_NULL_RETURN(context, std::nullopt);
758 auto overlayManager = context->GetOverlayManager();
759 CHECK_NULL_RETURN(overlayManager, std::nullopt);
760 return overlayManager->GetBottomOrder();
761 }
762
HideDialogSubWindow(int32_t instanceId)763 void SubwindowManager::HideDialogSubWindow(int32_t instanceId)
764 {
765 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide dialog subwindow enter");
766 #ifdef OHOS_STANDARD_SYSTEM
767 auto subwindow = GetSubwindowByType(instanceId, SubwindowType::TYPE_DIALOG);
768 #else
769 auto subwindow = GetSubwindowByType(GetParentContainerId(instanceId) != -1 ?
770 GetParentContainerId(instanceId) : instanceId, SubwindowType::TYPE_DIALOG);
771 #endif
772 CHECK_NULL_VOID(subwindow);
773 auto overlay = subwindow->GetOverlayManager();
774 CHECK_NULL_VOID(overlay);
775 if (overlay->GetDialogMap().size() == 0) {
776 subwindow->HideSubWindowNG();
777 } else {
778 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "fail to hide dialog subwindow, instanceId is %{public}d.", instanceId);
779 }
780 }
781
AddDialogSubwindow(int32_t instanceId,const RefPtr<Subwindow> & subwindow)782 void SubwindowManager::AddDialogSubwindow(int32_t instanceId, const RefPtr<Subwindow>& subwindow)
783 {
784 if (!subwindow) {
785 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add dialog subwindow failed, the subwindow is null.");
786 return;
787 }
788 std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
789 auto result = dialogSubwindowMap_.try_emplace(instanceId, subwindow);
790 if (!result.second) {
791 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add dialog failed of this instance %{public}d", instanceId);
792 return;
793 }
794 AddInstanceSubwindowMap(subwindow->GetChildContainerId(), subwindow);
795 }
796
GetDialogSubwindow(int32_t instanceId)797 const RefPtr<Subwindow> SubwindowManager::GetDialogSubwindow(int32_t instanceId)
798 {
799 std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
800 auto result = dialogSubwindowMap_.find(instanceId);
801 if (result != dialogSubwindowMap_.end()) {
802 return result->second;
803 } else {
804 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to get subwindow in dialogSubwindowMap_, instanceId is %{public}d",
805 instanceId);
806 return nullptr;
807 }
808 }
809
SetCurrentDialogSubwindow(const RefPtr<Subwindow> & subwindow)810 void SubwindowManager::SetCurrentDialogSubwindow(const RefPtr<Subwindow>& subwindow)
811 {
812 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set current dialog subwindow enter");
813 std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
814 currentDialogSubwindow_ = subwindow;
815 }
816
GetCurrentDialogWindow()817 const RefPtr<Subwindow>& SubwindowManager::GetCurrentDialogWindow()
818 {
819 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get current dialog window enter");
820 std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
821 return currentDialogSubwindow_;
822 }
823
GetOrCreateSubWindow(bool isDialog)824 RefPtr<Subwindow> SubwindowManager::GetOrCreateSubWindow(bool isDialog)
825 {
826 auto containerId = Container::CurrentId();
827 auto subwindow = GetDialogSubwindow(containerId);
828 if (!subwindow) {
829 subwindow = Subwindow::CreateSubwindow(containerId);
830 CHECK_NULL_RETURN(subwindow, nullptr);
831 if (isDialog) {
832 CHECK_NULL_RETURN(subwindow->CheckHostWindowStatus(), nullptr);
833 }
834 AddDialogSubwindow(containerId, subwindow);
835 }
836 return subwindow;
837 }
838
GetOrCreateSystemSubWindow(int32_t containerId)839 RefPtr<Subwindow> SubwindowManager::GetOrCreateSystemSubWindow(int32_t containerId)
840 {
841 auto subwindow = GetSystemToastWindow(containerId);
842 if (!subwindow) {
843 subwindow = Subwindow::CreateSubwindow(containerId);
844 CHECK_NULL_RETURN(subwindow, nullptr);
845 AddSystemToastWindow(containerId, subwindow);
846 }
847 return subwindow;
848 }
849
ShowToastNG(const NG::ToastInfo & toastInfo,std::function<void (int32_t)> && callback)850 void SubwindowManager::ShowToastNG(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
851 {
852 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show toast ng enter");
853 auto containerId = Container::CurrentId();
854 auto windowType = GetToastWindowType(containerId);
855 auto container = Container::GetContainer(containerId);
856 CHECK_NULL_VOID(container);
857 auto windowId = container->GetWindowId();
858 // Get the parent window ID before the asynchronous operation
859 auto mainWindowId = container->GetParentMainWindowId(windowId);
860 // for ability
861 auto taskExecutor = Container::CurrentTaskExecutor();
862 CHECK_NULL_VOID(taskExecutor);
863 taskExecutor->PostTask(
864 [containerId, toastInfo, callbackParam = std::move(callback), windowType, mainWindowId] {
865 auto subwindow = SubwindowManager::GetInstance()->GetOrCreateToastWindowNG(
866 containerId, windowType, mainWindowId);
867 CHECK_NULL_VOID(subwindow);
868 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before show toast : %{public}d", containerId);
869 subwindow->ShowToast(toastInfo, std::move(const_cast<std::function<void(int32_t)>&&>(callbackParam)));
870 },
871 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowToastNG");
872 }
873
GetToastWindowType(int32_t instanceId)874 ToastWindowType SubwindowManager::GetToastWindowType(int32_t instanceId)
875 {
876 auto parentContainer = Container::GetContainer(instanceId);
877 CHECK_NULL_RETURN(parentContainer, ToastWindowType::TOAST_IN_TYPE_TOAST);
878 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "GetToastWindowType instanceId: %{public}d", instanceId);
879 // toast window should be TOAST_IN_TYPE_APP_SUB_WINDOW when parent window is dialog window.
880 if (parentContainer->IsMainWindow() || parentContainer->IsSubWindow() ||
881 parentContainer->IsDialogWindow()) {
882 return ToastWindowType::TOAST_IN_TYPE_APP_SUB_WINDOW;
883 } else if (parentContainer->IsScenceBoardWindow()) {
884 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_FLOAT;
885 } else if (parentContainer->IsSystemWindow()) {
886 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_SUB_WINDOW;
887 } else if (parentContainer->IsUIExtensionWindow()) {
888 if (parentContainer->IsHostMainWindow() || parentContainer->IsHostSubWindow() ||
889 parentContainer->IsHostDialogWindow()) {
890 return ToastWindowType::TOAST_IN_TYPE_APP_SUB_WINDOW;
891 } else if (parentContainer->IsHostSceneBoardWindow()) {
892 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_FLOAT;
893 } else if (parentContainer->IsHostSystemWindow()) {
894 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_SUB_WINDOW;
895 }
896 }
897 return ToastWindowType::TOAST_IN_TYPE_TOAST;
898 }
899
ShowToast(const NG::ToastInfo & toastInfo,std::function<void (int32_t)> && callback)900 void SubwindowManager::ShowToast(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
901 {
902 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show toast enter");
903 auto containerId = Container::CurrentId();
904 auto isTopMost = toastInfo.showMode == NG::ToastShowMode::TOP_MOST;
905 // for pa service
906 if ((isTopMost && containerId >= MIN_PA_SERVICE_ID && containerId < MIN_SUBCONTAINER_ID) ||
907 (!isTopMost && containerId >= MIN_PA_SERVICE_ID) || containerId < 0) {
908 auto subwindow = toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST ?
909 GetOrCreateSystemSubWindow(containerId) : GetOrCreateSubWindow();
910 CHECK_NULL_VOID(subwindow);
911 subwindow->SetIsSystemTopMost(toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
912 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before show toast");
913 subwindow->ShowToast(toastInfo, std::move(callback));
914 } else {
915 // for ability
916 auto parentContainer = Container::GetContainer(containerId);
917 // in scenceboard, system_top_most needs to go the old way,
918 // default and top_most need to go showToastNG
919 if (toastInfo.showMode == NG::ToastShowMode::TOP_MOST ||
920 (parentContainer && parentContainer->IsScenceBoardWindow() &&
921 toastInfo.showMode != NG::ToastShowMode::SYSTEM_TOP_MOST)) {
922 ShowToastNG(toastInfo, std::move(callback));
923 return;
924 }
925 auto taskExecutor = Container::CurrentTaskExecutor();
926 CHECK_NULL_VOID(taskExecutor);
927 taskExecutor->PostTask(
928 [containerId, toastInfo, callbackParam = std::move(callback)] {
929 auto manager = SubwindowManager::GetInstance();
930 CHECK_NULL_VOID(manager);
931 auto subwindow = manager->GetOrCreateToastWindow(containerId, toastInfo.showMode);
932 CHECK_NULL_VOID(subwindow);
933 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before show toast : %{public}d", containerId);
934 subwindow->ShowToast(toastInfo, std::move(const_cast<std::function<void(int32_t)>&&>(callbackParam)));
935 },
936 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowToast");
937 }
938 }
939
CloseToast(const int32_t toastId,const NG::ToastShowMode & showMode,std::function<void (int32_t)> && callback)940 void SubwindowManager::CloseToast(
941 const int32_t toastId, const NG::ToastShowMode& showMode, std::function<void(int32_t)>&& callback)
942 {
943 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close toast enter");
944 auto containerId = Container::CurrentId();
945
946 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
947 // for pa service
948 auto subwindow = showMode == NG::ToastShowMode::SYSTEM_TOP_MOST ?
949 GetSystemToastWindow(containerId) : GetDialogSubwindow(containerId);
950 CHECK_NULL_VOID(subwindow);
951 subwindow->SetIsSystemTopMost(showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
952 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before close toast");
953 subwindow->CloseToast(toastId, std::move(callback));
954 } else {
955 // for ability
956 if (showMode == NG::ToastShowMode::TOP_MOST) {
957 auto subwindow =
958 containerId < MIN_SUBCONTAINER_ID ? GetToastSubwindow(containerId) : GetSubwindow(containerId);
959 CHECK_NULL_VOID(subwindow);
960 subwindow->CloseToast(toastId, std::move(callback));
961 return;
962 }
963 auto manager = SubwindowManager::GetInstance();
964 CHECK_NULL_VOID(manager);
965 auto subwindow = (showMode == NG::ToastShowMode::SYSTEM_TOP_MOST && containerId < MIN_SUBCONTAINER_ID)
966 ? GetSystemToastWindow(containerId)
967 : GetSubwindow(containerId);
968 CHECK_NULL_VOID(subwindow);
969 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before close toast : %{public}d", containerId);
970 subwindow->CloseToast(toastId, std::move(callback));
971 }
972 }
973
GetOrCreateToastWindow(int32_t containerId,const NG::ToastShowMode & showMode)974 RefPtr<Subwindow> SubwindowManager::GetOrCreateToastWindow(int32_t containerId, const NG::ToastShowMode& showMode)
975 {
976 auto isSystemTopMost = (showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
977 auto subwindow = (isSystemTopMost && containerId < MIN_SUBCONTAINER_ID) ? GetSystemToastWindow(containerId)
978 : GetSubwindow(containerId);
979 if (!IsSubwindowExist(subwindow)) {
980 subwindow = Subwindow::CreateSubwindow(containerId);
981 subwindow->SetIsSystemTopMost(isSystemTopMost);
982 subwindow->SetAboveApps(showMode == NG::ToastShowMode::TOP_MOST);
983 subwindow->InitContainer();
984 CHECK_NULL_RETURN(subwindow->GetIsRosenWindowCreate(), nullptr);
985 if (isSystemTopMost) {
986 AddSystemToastWindow(containerId, subwindow);
987 } else {
988 AddSubwindow(containerId, subwindow);
989 }
990 }
991
992 return subwindow;
993 }
994
GetOrCreateToastWindowNG(int32_t containerId,const ToastWindowType & windowType,uint32_t mainWindowId)995 RefPtr<Subwindow> SubwindowManager::GetOrCreateToastWindowNG(int32_t containerId,
996 const ToastWindowType& windowType, uint32_t mainWindowId)
997 {
998 RefPtr<Subwindow> subwindow = GetToastSubwindow(containerId);
999 if (!subwindow) {
1000 subwindow = Subwindow::CreateSubwindow(containerId);
1001 if (!subwindow) {
1002 TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "create toast subwindow failed");
1003 return nullptr;
1004 }
1005 subwindow->SetToastWindowType(windowType);
1006 subwindow->SetMainWindowId(mainWindowId);
1007 subwindow->InitContainer();
1008 AddToastSubwindow(containerId, subwindow);
1009 }
1010 return subwindow;
1011 }
1012
ClearToastInSubwindow()1013 void SubwindowManager::ClearToastInSubwindow()
1014 {
1015 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear toast in subwindow enter");
1016 auto containerId = Container::CurrentId();
1017 // Get active container when current instanceid is less than 0
1018 if (containerId < 0) {
1019 auto container = Container::GetActive();
1020 if (container) {
1021 containerId = container->GetInstanceId();
1022 }
1023 }
1024 RefPtr<Subwindow> subwindow;
1025 // The main window does not need to clear Toast
1026 if (containerId != -1 && containerId < MIN_SUBCONTAINER_ID) {
1027 // get the subwindow which overlay node in, not current
1028 subwindow = GetToastSubwindow(containerId);
1029 }
1030 if (subwindow) {
1031 subwindow->ClearToast();
1032 }
1033 }
1034
ShowDialog(const std::string & title,const std::string & message,const std::vector<ButtonInfo> & buttons,bool autoCancel,std::function<void (int32_t,int32_t)> && napiCallback,const std::set<std::string> & dialogCallbacks)1035 void SubwindowManager::ShowDialog(const std::string& title, const std::string& message,
1036 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& napiCallback,
1037 const std::set<std::string>& dialogCallbacks)
1038 {
1039 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog enter");
1040 auto containerId = Container::CurrentId();
1041 // Get active container when current instanceid is less than 0
1042 if (containerId < 0) {
1043 auto container = Container::GetActive();
1044 if (container) {
1045 containerId = container->GetInstanceId();
1046 }
1047 }
1048 // for pa service
1049 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
1050 auto subwindow = GetOrCreateSubWindow();
1051 CHECK_NULL_VOID(subwindow);
1052 subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
1053 // for ability
1054 } else {
1055 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
1056 if (!IsSubwindowExist(subwindow)) {
1057 subwindow = Subwindow::CreateSubwindow(containerId);
1058 CHECK_NULL_VOID(subwindow);
1059 CHECK_NULL_VOID(subwindow->CheckHostWindowStatus());
1060 subwindow->InitContainer();
1061 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
1062 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
1063 }
1064 subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
1065 }
1066 }
1067
ShowDialog(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && napiCallback,const std::set<std::string> & dialogCallbacks)1068 void SubwindowManager::ShowDialog(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
1069 std::function<void(int32_t, int32_t)>&& napiCallback, const std::set<std::string>& dialogCallbacks)
1070 {
1071 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog enter");
1072 auto containerId = Container::CurrentId();
1073 // Get active container when current instanceid is less than 0
1074 if (containerId < 0) {
1075 auto container = Container::GetActive();
1076 if (container) {
1077 containerId = container->GetInstanceId();
1078 }
1079 }
1080 // for pa service
1081 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
1082 auto subwindow = GetOrCreateSubWindow(true);
1083 CHECK_NULL_VOID(subwindow);
1084 subwindow->ShowDialog(dialogAttr, buttons, std::move(napiCallback), dialogCallbacks);
1085 // for ability
1086 } else {
1087 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
1088 if (!IsSubwindowExist(subwindow)) {
1089 subwindow = Subwindow::CreateSubwindow(containerId);
1090 CHECK_NULL_VOID(subwindow);
1091 CHECK_NULL_VOID(subwindow->CheckHostWindowStatus());
1092 subwindow->InitContainer();
1093 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
1094 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
1095 }
1096 subwindow->ShowDialog(dialogAttr, buttons, std::move(napiCallback), dialogCallbacks);
1097 }
1098 }
1099
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)1100 void SubwindowManager::ShowActionMenu(
1101 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
1102 {
1103 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show action menu enter");
1104 auto containerId = Container::CurrentId();
1105 // Get active container when current instanceid is less than 0
1106 if (containerId < 0) {
1107 auto container = Container::GetActive();
1108 if (container) {
1109 containerId = container->GetInstanceId();
1110 }
1111 }
1112 // for pa service
1113 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
1114 auto subwindow = GetOrCreateSubWindow(true);
1115 CHECK_NULL_VOID(subwindow);
1116 subwindow->ShowActionMenu(title, button, std::move(callback));
1117 // for ability
1118 } else {
1119 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
1120 if (!IsSubwindowExist(subwindow)) {
1121 subwindow = Subwindow::CreateSubwindow(containerId);
1122 CHECK_NULL_VOID(subwindow);
1123 CHECK_NULL_VOID(subwindow->CheckHostWindowStatus());
1124 subwindow->InitContainer();
1125 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
1126 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
1127 }
1128 subwindow->ShowActionMenu(title, button, std::move(callback));
1129 }
1130 }
1131
CloseDialog(int32_t instanceId)1132 void SubwindowManager::CloseDialog(int32_t instanceId)
1133 {
1134 auto subwindow = GetDialogSubwindow(instanceId);
1135 if (!subwindow) {
1136 subwindow = GetSubwindowByType(instanceId, SubwindowType::TYPE_DIALOG);
1137 if (subwindow) {
1138 subwindow->Close();
1139 return;
1140 }
1141 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get dialog subwindow failed.");
1142 return;
1143 }
1144 auto subContainerId = GetSubContainerId(instanceId);
1145 if (subContainerId > -1) {
1146 subwindow->CloseDialog(subContainerId);
1147 }
1148 }
1149
OpenCustomDialog(const PromptDialogAttr & dialogAttr,std::function<void (int32_t)> && callback)1150 void SubwindowManager::OpenCustomDialog(const PromptDialogAttr &dialogAttr, std::function<void(int32_t)> &&callback)
1151 {
1152 PromptDialogAttr tmpPromptAttr = dialogAttr;
1153 tmpPromptAttr.showInSubWindow = false;
1154 auto containerId = Container::CurrentId();
1155 // for pa service
1156 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "container %{public}d open the custom dialog", containerId);
1157 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
1158 auto subwindow = GetOrCreateSubWindow();
1159 CHECK_NULL_VOID(subwindow);
1160 subwindow->OpenCustomDialog(tmpPromptAttr, std::move(callback));
1161 // for ability
1162 } else {
1163 auto subwindow = GetSubwindowByType(containerId, SubwindowType::TYPE_DIALOG);
1164 if (!IsSubwindowExist(subwindow)) {
1165 subwindow = Subwindow::CreateSubwindow(containerId);
1166 CHECK_NULL_VOID(subwindow);
1167 CHECK_NULL_VOID(subwindow->CheckHostWindowStatus());
1168 subwindow->InitContainer();
1169 CHECK_NULL_VOID(subwindow->GetIsRosenWindowCreate());
1170 AddSubwindow(containerId, SubwindowType::TYPE_DIALOG, subwindow);
1171 }
1172 subwindow->OpenCustomDialog(tmpPromptAttr, std::move(callback));
1173 }
1174 return;
1175 }
1176
CloseCustomDialog(const int32_t dialogId)1177 void SubwindowManager::CloseCustomDialog(const int32_t dialogId)
1178 {
1179 auto containerId = Container::CurrentId();
1180 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "CloseCustomDialog dialogId = %{public}d, containerId = %{public}d.",
1181 dialogId, containerId);
1182 auto subwindow = GetDialogSubwindow(containerId);
1183 if (!subwindow) {
1184 return;
1185 }
1186 subwindow->CloseCustomDialog(dialogId);
1187 return;
1188 }
1189
CloseCustomDialog(const WeakPtr<NG::UINode> & node,std::function<void (int32_t)> && callback)1190 void SubwindowManager::CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)> &&callback)
1191 {
1192 auto containerId = Container::CurrentId();
1193 auto subwindow = GetDialogSubwindow(containerId);
1194 if (!subwindow) {
1195 return;
1196 }
1197 subwindow->CloseCustomDialog(node, std::move(callback));
1198 return;
1199 }
1200
HideSubWindowNG()1201 void SubwindowManager::HideSubWindowNG()
1202 {
1203 RefPtr<Subwindow> subwindow;
1204 auto container = Container::Current();
1205 CHECK_NULL_VOID(container);
1206 if (container->IsDialogContainer()) {
1207 subwindow = GetCurrentDialogWindow();
1208 } else {
1209 subwindow = GetCurrentWindow();
1210 }
1211 if (subwindow) {
1212 subwindow->HideSubWindowNG();
1213 } else {
1214 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "fail to hide subwindow, subwindow is null.");
1215 }
1216 }
1217
HideToastSubWindowNG()1218 void SubwindowManager::HideToastSubWindowNG()
1219 {
1220 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "hide toast subwindow enter");
1221 RefPtr<Subwindow> subwindow;
1222 auto container = Container::Current();
1223 auto containerId = Container::CurrentId();
1224 CHECK_NULL_VOID(container);
1225 if (container->IsDialogContainer()) {
1226 subwindow = GetCurrentDialogWindow();
1227 } else if (containerId != -1) {
1228 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
1229 GetParentContainerId(containerId) : containerId;
1230 subwindow = GetToastSubwindow(parentContainerId);
1231 }
1232 if (subwindow) {
1233 subwindow->HideSubWindowNG();
1234 } else {
1235 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "fail to hide toast subwindow, subwindow is null.");
1236 }
1237 }
1238
ResizeWindowForFoldStatus(int32_t parentContainerId)1239 void SubwindowManager::ResizeWindowForFoldStatus(int32_t parentContainerId)
1240 {
1241 auto containerId = Container::CurrentId();
1242 auto subwindow = parentContainerId < 0 || parentContainerId >= MIN_PA_SERVICE_ID ?
1243 GetDialogSubwindow(parentContainerId) : GetToastSubwindow(containerId);
1244 if (!subwindow) {
1245 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW,
1246 "Get Subwindow error, containerId = %{public}d, parentContainerId = %{public}d", containerId,
1247 parentContainerId);
1248 return;
1249 }
1250 subwindow->ResizeWindowForFoldStatus(parentContainerId);
1251 }
1252
MarkSubwindowSafeAreaDirtyByType(std::shared_ptr<SubwindowManager> manager,int32_t containerId,SubwindowType type)1253 void MarkSubwindowSafeAreaDirtyByType(std::shared_ptr<SubwindowManager> manager,
1254 int32_t containerId, SubwindowType type)
1255 {
1256 CHECK_NULL_VOID(manager);
1257 auto subwindow = manager->GetSubwindowByType(containerId, type);
1258 if (subwindow) {
1259 subwindow->MarkDirtyDialogSafeArea();
1260 }
1261 }
1262
MarkDirtyDialogSafeArea()1263 void SubwindowManager::MarkDirtyDialogSafeArea()
1264 {
1265 auto containerId = Container::CurrentId();
1266 auto manager = SubwindowManager::GetInstance();
1267 MarkSubwindowSafeAreaDirtyByType(manager, containerId, SubwindowType::TYPE_DIALOG);
1268 MarkSubwindowSafeAreaDirtyByType(manager, containerId, SubwindowType::TYPE_MENU);
1269 MarkSubwindowSafeAreaDirtyByType(manager, containerId, SubwindowType::TYPE_POPUP);
1270 MarkSubwindowSafeAreaDirtyByType(manager, containerId, SubwindowType::TYPE_TOP_MOST_TOAST);
1271 }
1272
HideSystemTopMostWindow()1273 void SubwindowManager::HideSystemTopMostWindow()
1274 {
1275 auto containerId = Container::CurrentId();
1276 if (containerId < 0) {
1277 auto container = Container::GetActive();
1278 if (container) {
1279 containerId = container->GetInstanceId();
1280 }
1281 }
1282 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
1283 GetParentContainerId(containerId) : containerId;
1284 auto subwindow = GetSystemToastWindow(parentContainerId);
1285 if (subwindow) {
1286 subwindow->HideSubWindowNG();
1287 } else {
1288 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "can not find systemTopMost window when hide window");
1289 }
1290 }
1291
ClearToastInSystemSubwindow()1292 void SubwindowManager::ClearToastInSystemSubwindow()
1293 {
1294 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear toast in system subwindow enter");
1295 auto containerId = Container::CurrentId();
1296 if (containerId < 0) {
1297 auto container = Container::GetActive();
1298 if (container) {
1299 containerId = container->GetInstanceId();
1300 }
1301 }
1302 RefPtr<Subwindow> subwindow;
1303 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1304 if (containerId != -1 && containerId < MIN_SUBCONTAINER_ID) {
1305 subwindow = GetSystemToastWindow(containerId);
1306 }
1307 } else {
1308 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
1309 GetParentContainerId(containerId) : containerId;
1310 subwindow = GetSystemToastWindow(parentContainerId);
1311 }
1312 if (subwindow) {
1313 subwindow->ClearToast();
1314 } else {
1315 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "can not find systemTopMost window when clear system toast");
1316 }
1317 }
1318
OnUIExtensionWindowSizeChange(int32_t instanceId,Rect windowRect,WindowSizeChangeReason reason)1319 void SubwindowManager::OnUIExtensionWindowSizeChange(int32_t instanceId, Rect windowRect, WindowSizeChangeReason reason)
1320 {
1321 auto container = Container::GetContainer(instanceId);
1322 CHECK_NULL_VOID(container);
1323 if (!container->IsUIExtensionWindow() || uiExtensionWindowRect_ == windowRect) {
1324 return;
1325 }
1326 uiExtensionWindowRect_ = windowRect;
1327
1328 auto allSubcontainerId = GetAllSubContainerId(instanceId);
1329 std::for_each(allSubcontainerId.begin(), allSubcontainerId.end(), [](int32_t subContainerId) {
1330 auto subContainer = Container::GetContainer(subContainerId);
1331 CHECK_NULL_VOID(subContainer);
1332 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(subContainer->GetPipelineContext());
1333 CHECK_NULL_VOID(pipeline);
1334 auto overlayManager = pipeline->GetOverlayManager();
1335 CHECK_NULL_VOID(overlayManager);
1336 overlayManager->OnUIExtensionWindowSizeChange();
1337 });
1338 }
1339
FlushSubWindowUITasks(int32_t instanceId)1340 void SubwindowManager::FlushSubWindowUITasks(int32_t instanceId)
1341 {
1342 auto subwindowContainerId = GetSubContainerId(instanceId);
1343 if (subwindowContainerId >= MIN_SUBCONTAINER_ID) {
1344 auto subPipline = NG::PipelineContext::GetContextByContainerId(subwindowContainerId);
1345 CHECK_NULL_VOID(subPipline);
1346 ContainerScope scope(subwindowContainerId);
1347 subPipline->FlushUITasks();
1348 }
1349 }
1350
IsSubwindowExist(RefPtr<Subwindow> subwindow)1351 bool SubwindowManager::IsSubwindowExist(RefPtr<Subwindow> subwindow)
1352 {
1353 return subwindow && subwindow->GetIsRosenWindowCreate();
1354 }
1355
GetSubwindowDialogNodeWithExistContent(const RefPtr<NG::UINode> & node)1356 RefPtr<NG::FrameNode> SubwindowManager::GetSubwindowDialogNodeWithExistContent(const RefPtr<NG::UINode>& node)
1357 {
1358 for (auto &overlay : GetAllSubOverlayManager()) {
1359 CHECK_NULL_RETURN(overlay, nullptr);
1360 auto dialogNode = overlay->GetDialogNodeWithExistContent(node);
1361 if (dialogNode) {
1362 return dialogNode;
1363 }
1364 }
1365 return nullptr;
1366 }
1367
MarkSetSubwindowRect(const NG::RectF & rect,int32_t instanceId,SubwindowType type)1368 void SubwindowManager::MarkSetSubwindowRect(const NG::RectF& rect, int32_t instanceId, SubwindowType type)
1369 {
1370 RefPtr<Subwindow> subwindow;
1371 if (instanceId != -1) {
1372 // get the subwindow which overlay node in, not current
1373 subwindow = GetSubwindowByType(instanceId, type);
1374 } else {
1375 subwindow = GetCurrentWindow();
1376 }
1377
1378 if (subwindow) {
1379 subwindow->SetRect(rect);
1380 } else {
1381 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "can not get subwindow, set rect failed");
1382 }
1383 }
1384
SetRect(const NG::RectF & rect,int32_t instanceId)1385 void SubwindowManager::SetRect(const NG::RectF& rect, int32_t instanceId)
1386 {
1387 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set subwindow rect enter");
1388 MarkSetSubwindowRect(rect, instanceId, SubwindowType::TYPE_DIALOG);
1389 MarkSetSubwindowRect(rect, instanceId, SubwindowType::TYPE_MENU);
1390 MarkSetSubwindowRect(rect, instanceId, SubwindowType::TYPE_POPUP);
1391 }
1392
IsFreeMultiWindow(int32_t instanceId) const1393 bool SubwindowManager::IsFreeMultiWindow(int32_t instanceId) const
1394 {
1395 auto subWindow = SubwindowManager::GetInstance()->GetSubwindow(instanceId);
1396 CHECK_NULL_RETURN(subWindow, false);
1397 return subWindow->IsFreeMultiWindow();
1398 }
1399
GetAllSubOverlayManager()1400 const std::vector<RefPtr<NG::OverlayManager>> SubwindowManager::GetAllSubOverlayManager()
1401 {
1402 std::lock_guard<std::mutex> lock(subwindowMutex_);
1403 std::vector<RefPtr<NG::OverlayManager>> subOverlayManager;
1404 subOverlayManager.reserve(subwindowMap_.size());
1405 auto iter = subwindowMap_.begin();
1406 while (iter != subwindowMap_.end()) {
1407 auto subwindow = iter->second;
1408 if (subwindow) {
1409 subOverlayManager.push_back(subwindow->GetOverlayManager());
1410 }
1411 iter++;
1412 }
1413 return subOverlayManager;
1414 }
1415
GetCurrentSubwindowKey(int32_t instanceId,SubwindowType windowType)1416 SubwindowKey SubwindowManager::GetCurrentSubwindowKey(int32_t instanceId, SubwindowType windowType)
1417 {
1418 uint64_t displayId = 0;
1419 SubwindowKey searchKey;
1420 searchKey.instanceId = instanceId;
1421 searchKey.subwindowType = static_cast<int32_t>(windowType);
1422 if (windowType == SubwindowType::TYPE_POPUP || windowType == SubwindowType::TYPE_MENU) {
1423 windowType = SubwindowType::TYPE_DIALOG;
1424 }
1425 searchKey.windowType = windowType;
1426 searchKey.foldStatus = FoldStatus::UNKNOWN;
1427 auto container = Container::GetContainer(instanceId);
1428 if (container) {
1429 displayId = container->GetCurrentDisplayId();
1430 searchKey.foldStatus =
1431 isSuperFoldDisplayDevice_ && (displayId == DEFAULT_DISPLAY_ID || displayId == VIRTUAL_DISPLAY_ID)
1432 ? container->GetFoldStatusFromListener()
1433 : FoldStatus::UNKNOWN;
1434 }
1435
1436 searchKey.displayId = displayId;
1437 return searchKey;
1438 }
1439
ShowSelectOverlay(const RefPtr<NG::FrameNode> & overlayNode)1440 int32_t SubwindowManager::ShowSelectOverlay(const RefPtr<NG::FrameNode>& overlayNode)
1441 {
1442 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Show selectOverlay enter.");
1443 CHECK_NULL_RETURN(overlayNode, -1);
1444 auto containerId = Container::CurrentIdSafelyWithCheck();
1445 auto windowType = GetToastWindowType(containerId);
1446 auto container = Container::GetContainer(containerId);
1447 CHECK_NULL_RETURN(container, -1);
1448 auto windowId = container->GetWindowId();
1449 // Get the parent window ID before the asynchronous operation
1450 auto mainWindowId = container->GetParentMainWindowId(windowId);
1451 auto subwindow = GetOrCreateSelectOverlayWindow(containerId, windowType, mainWindowId);
1452 if (!IsSubwindowExist(subwindow)) {
1453 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Get or create SelectOverlay subwindow failed.");
1454 return -1;
1455 }
1456 auto isShowSuccess = subwindow->ShowSelectOverlay(overlayNode);
1457 if (!isShowSuccess) {
1458 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Show selectOverlay subwindow failed.");
1459 return -1;
1460 }
1461 return containerId;
1462 }
1463
HideSelectOverlay(const int32_t instanceId)1464 void SubwindowManager::HideSelectOverlay(const int32_t instanceId)
1465 {
1466 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Hide selectOverlay subwindow enter.");
1467 auto subwindow = GetSelectOverlaySubwindow(instanceId);
1468 if (subwindow) {
1469 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Hide the existed selectOverlay subwindow.");
1470 subwindow->HideSubWindowNG();
1471 } else {
1472 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to hide selectOverlay subwindow, subwindow is not existed.");
1473 }
1474 }
1475
GetSelectOverlaySubwindow(int32_t instanceId)1476 const RefPtr<Subwindow> SubwindowManager::GetSelectOverlaySubwindow(int32_t instanceId)
1477 {
1478 return GetSubwindowByType(instanceId, SubwindowType::TYPE_SELECT_MENU);
1479 }
1480
AddSelectOverlaySubwindow(int32_t instanceId,RefPtr<Subwindow> subwindow)1481 void SubwindowManager::AddSelectOverlaySubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
1482 {
1483 if (!subwindow) {
1484 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add selectOverlay subwindow failed, subwindow is null.");
1485 return;
1486 }
1487
1488 if (!subwindow->GetIsRosenWindowCreate()) {
1489 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add selectOverlay subwindow failed, subwindow is invalid.");
1490 subwindow->DestroyWindow();
1491 return;
1492 }
1493
1494 AddSubwindow(instanceId, SubwindowType::TYPE_SELECT_MENU, subwindow);
1495 }
1496
GetOrCreateSelectOverlayWindow(int32_t containerId,const ToastWindowType & windowType,uint32_t mainWindowId)1497 RefPtr<Subwindow> SubwindowManager::GetOrCreateSelectOverlayWindow(
1498 int32_t containerId, const ToastWindowType& windowType, uint32_t mainWindowId)
1499 {
1500 RefPtr<Subwindow> subwindow = GetSelectOverlaySubwindow(containerId);
1501 if (!subwindow) {
1502 subwindow = Subwindow::CreateSubwindow(containerId);
1503 if (!subwindow) {
1504 TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "Create selectOverlay subwindow failed.");
1505 return nullptr;
1506 }
1507 subwindow->SetIsSelectOverlaySubWindow(true);
1508 subwindow->SetToastWindowType(windowType);
1509 subwindow->SetMainWindowId(mainWindowId);
1510 subwindow->InitContainer();
1511 if (!subwindow->GetIsRosenWindowCreate()) {
1512 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Create selectOverlay subwindow failed, subwindow is invalid.");
1513 subwindow->DestroyWindow();
1514 return nullptr;
1515 }
1516 AddSelectOverlaySubwindow(containerId, subwindow);
1517 }
1518 return subwindow;
1519 }
1520
SetSelectOverlayHotAreas(const std::vector<Rect> & rects,int32_t nodeId,int32_t instanceId)1521 void SubwindowManager::SetSelectOverlayHotAreas(const std::vector<Rect>& rects, int32_t nodeId, int32_t instanceId)
1522 {
1523 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Set selectOverlay hot areas enter.");
1524 auto subwindow = GetSelectOverlaySubwindow(instanceId);
1525 if (subwindow) {
1526 subwindow->SetHotAreas(rects, nodeId);
1527 } else {
1528 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to set selectOverlay subwindow hotAreas, subwindow is null.");
1529 }
1530 }
1531
DeleteSelectOverlayHotAreas(int32_t instanceId,int32_t nodeId)1532 void SubwindowManager::DeleteSelectOverlayHotAreas(int32_t instanceId, int32_t nodeId)
1533 {
1534 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Delete selectOverlay subwindow hot areas enter.");
1535 auto subwindow = GetSelectOverlaySubwindow(instanceId);
1536 if (subwindow) {
1537 subwindow->DeleteHotAreas(nodeId);
1538 } else {
1539 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Fail to delete selectOverlay subwindow hotAreas, subwindow is null.");
1540 }
1541 }
1542
IsWindowEnableSubWindowMenu(const int32_t instanceId,const RefPtr<NG::FrameNode> & callerFrameNode)1543 bool SubwindowManager::IsWindowEnableSubWindowMenu(
1544 const int32_t instanceId, const RefPtr<NG::FrameNode>& callerFrameNode)
1545 {
1546 auto container = Container::GetContainer(instanceId);
1547 CHECK_NULL_RETURN(container, false);
1548
1549 if (instanceId >= MIN_SUBCONTAINER_ID) {
1550 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Subwindow does not support create subwindow menu.");
1551 return false;
1552 }
1553
1554 if (container->IsUIExtensionWindow()) {
1555 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "UIExtensionWindow does not support create subwindow menu.");
1556 return false;
1557 }
1558
1559 if (container->IsScenceBoardWindow()) {
1560 if (!container->IsSceneBoardEnabled()) {
1561 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Disabled sceneBoard does not support create subwindow menu.");
1562 return false;
1563 }
1564 // If the callerFrameNode is on the lock screen, the subwinow menu will be obscured by the lock screen.
1565 if (Container::IsNodeInKeyGuardWindow(callerFrameNode)) {
1566 TAG_LOGW(
1567 AceLogTag::ACE_SUB_WINDOW, "The node in the key guard window does not support create subwindow menu.");
1568 return false;
1569 }
1570
1571 return true;
1572 }
1573
1574 if (container->IsSubWindow() || container->IsMainWindow() || container->IsDialogWindow()) {
1575 return true;
1576 }
1577
1578 if (container->IsSystemWindow()) {
1579 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "System window does not support create subwindow menu.");
1580 return false;
1581 }
1582
1583 return false;
1584 }
1585
GetSubwindowByType(int32_t instanceId,SubwindowType windowType)1586 const RefPtr<Subwindow> SubwindowManager::GetSubwindowByType(int32_t instanceId, SubwindowType windowType)
1587 {
1588 if (instanceId >= MIN_SUBCONTAINER_ID) {
1589 return GetSubwindowById(instanceId);
1590 }
1591
1592 auto index = static_cast<int32_t>(windowType);
1593 if (index >= static_cast<int32_t>(SubwindowType::SUB_WINDOW_TYPE_COUNT)) {
1594 return nullptr;
1595 }
1596 SubwindowKey searchKey = GetCurrentSubwindowKey(instanceId, windowType);
1597 std::lock_guard<std::mutex> lock(subwindowMutex_);
1598 auto result = subwindowMap_.find(searchKey);
1599 if (result != subwindowMap_.end()) {
1600 return result->second;
1601 } else {
1602 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Fail to find subwindow in subwindowMap_, searchKey is %{public}s.",
1603 searchKey.ToString().c_str());
1604 return nullptr;
1605 }
1606 }
1607
AddSubwindow(int32_t instanceId,SubwindowType windowType,RefPtr<Subwindow> subwindow)1608 void SubwindowManager::AddSubwindow(int32_t instanceId, SubwindowType windowType, RefPtr<Subwindow> subwindow)
1609 {
1610 if (!subwindow) {
1611 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add subwindow is nullptr.");
1612 return;
1613 }
1614 auto index = static_cast<int32_t>(windowType);
1615 if (index >= static_cast<int32_t>(SubwindowType::SUB_WINDOW_TYPE_COUNT)) {
1616 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add subwindow window scene/%{public}d is error.", index);
1617 return;
1618 }
1619 SubwindowKey searchKey = GetCurrentSubwindowKey(instanceId, windowType);
1620 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Add subwindow into map, searchKey is %{public}s, subwindow id is %{public}d.",
1621 searchKey.ToString().c_str(), subwindow->GetSubwindowId());
1622 std::lock_guard<std::mutex> lock(subwindowMutex_);
1623 auto result = subwindowMap_.try_emplace(searchKey, subwindow);
1624 if (!result.second) {
1625 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add failed of this searchkey, searchKey is %{public}s.",
1626 searchKey.ToString().c_str());
1627 return;
1628 }
1629 AddInstanceSubwindowMap(subwindow->GetChildContainerId(), subwindow);
1630 }
1631
GetSortSubwindow(int32_t instanceId)1632 const std::vector<RefPtr<Subwindow>> SubwindowManager::GetSortSubwindow(int32_t instanceId)
1633 {
1634 std::vector<RefPtr<Subwindow>> sortSubwindow;
1635 for (SubwindowType type : NORMAL_SUBWINDOW_TYPE) {
1636 auto subwindow = GetSubwindowByType(instanceId, type);
1637 if (subwindow) {
1638 sortSubwindow.push_back(subwindow);
1639 }
1640 }
1641
1642 std::sort(sortSubwindow.begin(), sortSubwindow.end(), [](RefPtr<Subwindow> first, RefPtr<Subwindow> second) {
1643 if (!first) {
1644 return false;
1645 }
1646 if (!second) {
1647 return true;
1648 }
1649 return first->GetSubwindowId() > second->GetSubwindowId();
1650 });
1651 return sortSubwindow;
1652 }
1653
GetIsExpandDisplay()1654 bool SubwindowManager::GetIsExpandDisplay()
1655 {
1656 auto pipeline = PipelineBase::GetCurrentContext();
1657 CHECK_NULL_RETURN(pipeline, false);
1658 auto theme = pipeline->GetTheme<SelectTheme>();
1659 CHECK_NULL_RETURN(theme, false);
1660 return theme->GetExpandDisplay();
1661 }
1662
GetOrCreateMenuSubWindow(int32_t instanceId)1663 RefPtr<Subwindow> SubwindowManager::GetOrCreateMenuSubWindow(int32_t instanceId)
1664 {
1665 SubwindowKey searchKey = GetCurrentSubwindowKey(instanceId, SubwindowType::TYPE_MENU);
1666 auto subwindow = GetSubwindowBySearchKey(searchKey);
1667 if (!IsSubwindowExist(subwindow)) {
1668 subwindow = Subwindow::CreateSubwindow(instanceId);
1669 CHECK_NULL_RETURN(subwindow, nullptr);
1670 subwindow->InitContainer();
1671 CHECK_NULL_RETURN(subwindow->GetIsRosenWindowCreate(), nullptr);
1672 AddSubwindowBySearchKey(searchKey, subwindow);
1673 } else if (subwindow->GetDetachState() == MenuWindowState::DETACHING) {
1674 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "recreate subwindow");
1675 RemoveSubwindowBySearchKey(searchKey);
1676 subwindow = Subwindow::CreateSubwindow(instanceId);
1677 CHECK_NULL_RETURN(subwindow, nullptr);
1678 subwindow->InitContainer();
1679 CHECK_NULL_RETURN(subwindow->GetIsRosenWindowCreate(), nullptr);
1680 AddSubwindowBySearchKey(searchKey, subwindow);
1681 }
1682 return subwindow;
1683 }
1684
GetSubwindowBySearchKey(const SubwindowKey & searchKey)1685 RefPtr<Subwindow> SubwindowManager::GetSubwindowBySearchKey(const SubwindowKey& searchKey)
1686 {
1687 std::lock_guard<std::mutex> lock(subwindowMutex_);
1688 auto result = subwindowMap_.find(searchKey);
1689 if (result != subwindowMap_.end()) {
1690 return result->second;
1691 } else {
1692 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "Fail to find subwindow in subwindowMap_, searchKey is %{public}s.",
1693 searchKey.ToString().c_str());
1694 return nullptr;
1695 }
1696 }
1697
RemoveSubwindowBySearchKey(const SubwindowKey & searchKey)1698 void SubwindowManager::RemoveSubwindowBySearchKey(const SubwindowKey& searchKey)
1699 {
1700 std::lock_guard<std::mutex> lock(subwindowMutex_);
1701 subwindowMap_.erase(searchKey);
1702 }
1703
AddSubwindowBySearchKey(const SubwindowKey & searchKey,const RefPtr<Subwindow> & subwindow)1704 void SubwindowManager::AddSubwindowBySearchKey(const SubwindowKey& searchKey, const RefPtr<Subwindow>& subwindow)
1705 {
1706 if (!subwindow) {
1707 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add subwindow is nullptr.");
1708 return;
1709 }
1710 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Add subwindow into map, searchKey is %{public}s, subwindow id is %{public}d.",
1711 searchKey.ToString().c_str(), subwindow->GetSubwindowId());
1712 std::lock_guard<std::mutex> lock(subwindowMutex_);
1713 auto result = subwindowMap_.try_emplace(searchKey, subwindow);
1714 if (!result.second) {
1715 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add failed of this searchkey, searchKey is %{public}s.",
1716 searchKey.ToString().c_str());
1717 return;
1718 }
1719 AddInstanceSubwindowMap(subwindow->GetChildContainerId(), subwindow);
1720 }
1721 } // namespace OHOS::Ace
1722