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
20 namespace OHOS::Ace {
21
22 std::mutex SubwindowManager::instanceMutex_;
23 std::shared_ptr<SubwindowManager> SubwindowManager::instance_;
24 thread_local RefPtr<Subwindow> SubwindowManager::currentSubwindow_;
25
GetInstance()26 std::shared_ptr<SubwindowManager> SubwindowManager::GetInstance()
27 {
28 std::lock_guard<std::mutex> lock(instanceMutex_);
29 if (!instance_) {
30 instance_ = std::make_shared<SubwindowManager>();
31 }
32 return instance_;
33 }
34
AddContainerId(uint32_t windowId, int32_t containerId)35 void SubwindowManager::AddContainerId(uint32_t windowId, int32_t containerId)
36 {
37 std::lock_guard<std::mutex> lock(mutex_);
38 auto result = containerMap_.try_emplace(windowId, containerId);
39 if (!result.second) {
40 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Already have container of this windowId, windowId: %{public}u", windowId);
41 }
42 }
43
RemoveContainerId(uint32_t windowId)44 void SubwindowManager::RemoveContainerId(uint32_t windowId)
45 {
46 std::lock_guard<std::mutex> lock(mutex_);
47 containerMap_.erase(windowId);
48 }
49
GetContainerId(uint32_t windowId)50 int32_t SubwindowManager::GetContainerId(uint32_t windowId)
51 {
52 std::lock_guard<std::mutex> lock(mutex_);
53 auto result = containerMap_.find(windowId);
54 if (result != containerMap_.end()) {
55 return result->second;
56 } else {
57 return -1;
58 }
59 }
60
AddParentContainerId(int32_t containerId, int32_t parentContainerId)61 void SubwindowManager::AddParentContainerId(int32_t containerId, int32_t parentContainerId)
62 {
63 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Container id is %{public}d, parent id is %{public}d.", containerId,
64 parentContainerId);
65 std::lock_guard<std::mutex> lock(parentMutex_);
66 parentContainerMap_.try_emplace(containerId, parentContainerId);
67 }
68
RemoveParentContainerId(int32_t containerId)69 void SubwindowManager::RemoveParentContainerId(int32_t containerId)
70 {
71 std::lock_guard<std::mutex> lock(parentMutex_);
72 parentContainerMap_.erase(containerId);
73 }
74
GetParentContainerId(int32_t containerId)75 int32_t SubwindowManager::GetParentContainerId(int32_t containerId)
76 {
77 std::lock_guard<std::mutex> lock(parentMutex_);
78 auto result = parentContainerMap_.find(containerId);
79 if (result != parentContainerMap_.end()) {
80 return result->second;
81 } else {
82 return -1;
83 }
84 }
85
GetSubContainerId(int32_t parentContainerId)86 int32_t SubwindowManager::GetSubContainerId(int32_t parentContainerId)
87 {
88 std::lock_guard<std::mutex> lock(parentMutex_);
89 for (auto it = parentContainerMap_.begin(); it != parentContainerMap_.end(); it++) {
90 if (it->second == parentContainerId) {
91 return it->first;
92 }
93 }
94 return -1;
95 }
96
AddSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)97 void SubwindowManager::AddSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
98 {
99 if (!subwindow) {
100 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add subwindow failed.");
101 return;
102 }
103 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Add subwindow into map, instanceId is %{public}d, subwindow id is %{public}d.",
104 instanceId, subwindow->GetSubwindowId());
105 std::lock_guard<std::mutex> lock(subwindowMutex_);
106 auto result = subwindowMap_.try_emplace(instanceId, subwindow);
107 if (!result.second) {
108 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add failed of this instance %{public}d", instanceId);
109 return;
110 }
111 }
112
AddToastSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)113 void SubwindowManager::AddToastSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
114 {
115 if (!subwindow) {
116 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add toast subwindow failed.");
117 return;
118 }
119 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "Add toast into map, instanceId is %{public}d, subwindow id is %{public}d.",
120 instanceId, subwindow->GetSubwindowId());
121 std::lock_guard<std::mutex> lock(toastMutex_);
122 auto result = toastWindowMap_.try_emplace(instanceId, subwindow);
123 if (!result.second) {
124 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add toast failed of this instance %{public}d", instanceId);
125 return;
126 }
127 }
128
AddSystemToastWindow(int32_t instanceId, RefPtr<Subwindow> subwindow)129 void SubwindowManager::AddSystemToastWindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
130 {
131 if (!subwindow) {
132 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "add system toast subwindow failed.");
133 return;
134 }
135 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW,
136 "Add system toast into map, instanceId is %{public}d, subwindow id is %{public}d.",
137 instanceId, subwindow->GetSubwindowId());
138 std::lock_guard<std::mutex> lock(systemToastMutex_);
139 auto result = systemToastWindowMap_.try_emplace(instanceId, subwindow);
140 if (!result.second) {
141 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add system toast failed of this instance %{public}d", instanceId);
142 return;
143 }
144 }
145
DeleteHotAreas(int32_t instanceId, int32_t nodeId)146 void SubwindowManager::DeleteHotAreas(int32_t instanceId, int32_t nodeId)
147 {
148 RefPtr<Subwindow> subwindow;
149 if (instanceId != -1) {
150 // get the subwindow which overlay node in, not current
151 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
152 } else {
153 subwindow = GetCurrentWindow();
154 }
155 if (subwindow) {
156 subwindow->DeleteHotAreas(nodeId);
157 }
158 }
RemoveSubwindow(int32_t instanceId)159 void SubwindowManager::RemoveSubwindow(int32_t instanceId)
160 {
161 std::lock_guard<std::mutex> lock(subwindowMutex_);
162 subwindowMap_.erase(instanceId);
163 }
164
GetSubwindow(int32_t instanceId)165 const RefPtr<Subwindow> SubwindowManager::GetSubwindow(int32_t instanceId)
166 {
167 std::lock_guard<std::mutex> lock(subwindowMutex_);
168 auto result = subwindowMap_.find(instanceId);
169 if (result != subwindowMap_.end()) {
170 return result->second;
171 } else {
172 return nullptr;
173 }
174 }
175
GetToastSubwindow(int32_t instanceId)176 const RefPtr<Subwindow> SubwindowManager::GetToastSubwindow(int32_t instanceId)
177 {
178 std::lock_guard<std::mutex> lock(toastMutex_);
179 auto result = toastWindowMap_.find(instanceId);
180 if (result != toastWindowMap_.end()) {
181 return result->second;
182 }
183 return nullptr;
184 }
185
GetSystemToastWindow(int32_t instanceId)186 const RefPtr<Subwindow> SubwindowManager::GetSystemToastWindow(int32_t instanceId)
187 {
188 std::lock_guard<std::mutex> lock(systemToastMutex_);
189 auto result = systemToastWindowMap_.find(instanceId);
190 if (result != systemToastWindowMap_.end()) {
191 return result->second;
192 }
193 return nullptr;
194 }
195
GetOrCreateSubwindow(int32_t instanceId)196 const RefPtr<Subwindow> SubwindowManager::GetOrCreateSubwindow(int32_t instanceId)
197 {
198 auto subwindow = GetSubwindow(instanceId);
199 if (subwindow) {
200 return subwindow;
201 }
202
203 subwindow = Subwindow::CreateSubwindow(instanceId);
204 if (!subwindow) {
205 TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "create sub window failed");
206 return nullptr;
207 }
208 AddSubwindow(instanceId, subwindow);
209 return subwindow;
210 }
211
GetDialogSubwindowInstanceId(int32_t SubwindowId)212 int32_t SubwindowManager::GetDialogSubwindowInstanceId(int32_t SubwindowId)
213 {
214 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get dialog subwindow instanceid enter");
215 std::lock_guard<std::mutex> lock(subwindowMutex_);
216 for (auto it = subwindowMap_.begin(); it != subwindowMap_.end(); it++) {
217 if (it->second->GetSubwindowId() == SubwindowId) {
218 return it->first;
219 }
220 }
221 return 0;
222 }
223
SetCurrentSubwindow(const RefPtr<Subwindow>& subwindow)224 void SubwindowManager::SetCurrentSubwindow(const RefPtr<Subwindow>& subwindow)
225 {
226 currentSubwindow_ = subwindow;
227 }
228
GetCurrentWindow()229 const RefPtr<Subwindow>& SubwindowManager::GetCurrentWindow()
230 {
231 return currentSubwindow_;
232 }
233
GetParentWindowRect()234 Rect SubwindowManager::GetParentWindowRect()
235 {
236 Rect rect;
237 CHECK_NULL_RETURN(currentSubwindow_, rect);
238 return currentSubwindow_->GetParentWindowRect();
239 }
240
ShowPreviewNG(bool isStartDraggingFromSubWindow)241 RefPtr<Subwindow> SubwindowManager::ShowPreviewNG(bool isStartDraggingFromSubWindow)
242 {
243 auto containerId = Container::CurrentId();
244 auto subwindow =
245 GetOrCreateSubwindow(containerId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(containerId) : containerId);
246 if (!subwindow) {
247 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
248 return nullptr;
249 }
250 if (!subwindow->ShowPreviewNG(isStartDraggingFromSubWindow)) {
251 return nullptr;
252 }
253 return subwindow;
254 }
255
ShowMenuNG(const RefPtr<NG::FrameNode>& menuNode, const NG::MenuParam& menuParam, const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)256 void SubwindowManager::ShowMenuNG(const RefPtr<NG::FrameNode>& menuNode, const NG::MenuParam& menuParam,
257 const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
258 {
259 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
260 CHECK_NULL_VOID(targetNode);
261 auto pipelineContext = targetNode->GetContext();
262 CHECK_NULL_VOID(pipelineContext);
263 auto containerId = pipelineContext->GetInstanceId();
264 auto subwindow = GetOrCreateSubwindow(containerId);
265 if (!subwindow) {
266 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
267 return;
268 }
269 subwindow->ShowMenuNG(menuNode, menuParam, targetNode, offset);
270 }
271
ShowMenuNG(std::function<void()>&& buildFunc, std::function<void()>&& previewBuildFunc, const NG::MenuParam& menuParam, const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)272 void SubwindowManager::ShowMenuNG(std::function<void()>&& buildFunc, std::function<void()>&& previewBuildFunc,
273 const NG::MenuParam& menuParam, const RefPtr<NG::FrameNode>& targetNode, const NG::OffsetF& offset)
274 {
275 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show menu ng enter");
276 CHECK_NULL_VOID(targetNode);
277 auto pipelineContext = targetNode->GetContext();
278 CHECK_NULL_VOID(pipelineContext);
279 auto containerId = pipelineContext->GetInstanceId();
280 auto subwindow = GetOrCreateSubwindow(containerId);
281 if (!subwindow) {
282 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
283 return;
284 }
285 subwindow->ShowMenuNG(std::move(buildFunc), std::move(previewBuildFunc), menuParam, targetNode, offset);
286 }
287
HidePreviewNG()288 void SubwindowManager::HidePreviewNG()
289 {
290 auto subwindow = GetCurrentWindow();
291 if (subwindow) {
292 subwindow->HidePreviewNG();
293 }
294 }
295
HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)296 void SubwindowManager::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)
297 {
298 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
299 auto subwindow = GetCurrentWindow();
300 if (subwindow) {
301 subwindow->HideMenuNG(menu, targetId);
302 }
303 }
304
HideMenuNG(bool showPreviewAnimation, bool startDrag)305 void SubwindowManager::HideMenuNG(bool showPreviewAnimation, bool startDrag)
306 {
307 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide menu ng enter");
308 auto subwindow = GetCurrentWindow();
309 if (subwindow) {
310 subwindow->HideMenuNG(showPreviewAnimation, startDrag);
311 }
312 }
313
UpdateHideMenuOffsetNG( const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)314 void SubwindowManager::UpdateHideMenuOffsetNG(
315 const NG::OffsetF& offset, float menuScale, bool isRedragStart, int32_t menuWrapperId)
316 {
317 auto subwindow = GetCurrentWindow();
318 if (subwindow) {
319 subwindow->UpdateHideMenuOffsetNG(offset, menuScale, isRedragStart, menuWrapperId);
320 }
321 }
322
ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode>& dragPreviewNode, const NG::OffsetF& offset)323 void SubwindowManager::ContextMenuSwitchDragPreviewAnimation(const RefPtr<NG::FrameNode>& dragPreviewNode,
324 const NG::OffsetF& offset)
325 {
326 CHECK_NULL_VOID(dragPreviewNode);
327 auto subwindow = GetCurrentWindow();
328 if (subwindow) {
329 subwindow->ContextMenuSwitchDragPreviewAnimationtNG(dragPreviewNode, offset);
330 }
331 }
332
UpdatePreviewPosition()333 void SubwindowManager::UpdatePreviewPosition()
334 {
335 auto subwindow = GetCurrentWindow();
336 if (subwindow) {
337 subwindow->UpdatePreviewPosition();
338 }
339 }
340
GetMenuPreviewCenter(NG::OffsetF& offset)341 bool SubwindowManager::GetMenuPreviewCenter(NG::OffsetF& offset)
342 {
343 auto subwindow = GetCurrentWindow();
344 if (subwindow) {
345 return subwindow->GetMenuPreviewCenter(offset);
346 }
347 return false;
348 }
349
ClearMenuNG(int32_t instanceId, int32_t targetId, bool inWindow, bool showAnimation)350 void SubwindowManager::ClearMenuNG(int32_t instanceId, int32_t targetId, bool inWindow, bool showAnimation)
351 {
352 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear menu ng enter");
353 RefPtr<Subwindow> subwindow;
354 if (instanceId != -1) {
355 #ifdef OHOS_STANDARD_SYSTEM
356 // get the subwindow which overlay node in, not current
357 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
358 #else
359 subwindow =
360 GetSubwindow(GetParentContainerId(instanceId) != -1 ? GetParentContainerId(instanceId) : instanceId);
361 #endif
362 } else {
363 subwindow = GetCurrentWindow();
364 }
365 if (subwindow) {
366 subwindow->ClearMenuNG(targetId, inWindow, showAnimation);
367 }
368 }
369
ClearPopupInSubwindow(int32_t instanceId)370 void SubwindowManager::ClearPopupInSubwindow(int32_t instanceId)
371 {
372 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear popup in subwindow enter");
373 RefPtr<Subwindow> subwindow;
374 if (instanceId != -1) {
375 // get the subwindow which overlay node in, not current
376 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
377 } else {
378 subwindow = GetCurrentWindow();
379 }
380 if (subwindow) {
381 subwindow->ClearPopupNG();
382 }
383 }
384
ShowPopupNG(const RefPtr<NG::FrameNode>& targetNode, const NG::PopupInfo& popupInfo, const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)385 void SubwindowManager::ShowPopupNG(const RefPtr<NG::FrameNode>& targetNode, const NG::PopupInfo& popupInfo,
386 const std::function<void(int32_t)>&& onWillDismiss, bool interactiveDismiss)
387 {
388 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show popup ng enter");
389 CHECK_NULL_VOID(targetNode);
390 auto pipelineContext = targetNode->GetContext();
391 CHECK_NULL_VOID(pipelineContext);
392 auto containerId = pipelineContext->GetInstanceId();
393
394 auto subwindow = GetOrCreateSubwindow(containerId);
395 if (!subwindow) {
396 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
397 return;
398 }
399 subwindow->ShowPopupNG(targetNode->GetId(), popupInfo, std::move(onWillDismiss), interactiveDismiss);
400 }
401
HidePopupNG(int32_t targetId, int32_t instanceId)402 void SubwindowManager::HidePopupNG(int32_t targetId, int32_t instanceId)
403 {
404 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "hide popup ng enter");
405 RefPtr<Subwindow> subwindow;
406 if (instanceId != -1) {
407 // get the subwindow which overlay node in, not current
408 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
409 } else {
410 subwindow = GetCurrentWindow();
411 }
412
413 if (subwindow) {
414 subwindow->HidePopupNG(targetId);
415 }
416 }
417
ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)418 void SubwindowManager::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
419 {
420 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show popup enter");
421 auto containerId = Container::CurrentId();
422 auto taskExecutor = Container::CurrentTaskExecutor();
423 CHECK_NULL_VOID(taskExecutor);
424 taskExecutor->PostTask(
425 [containerId, newComponentWeak = WeakPtr<Component>(newComponent), disableTouchEvent] {
426 auto subwindow = SubwindowManager::GetInstance()->GetOrCreateSubwindow(containerId);
427 if (!subwindow) {
428 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
429 return;
430 }
431 auto newComponent = newComponentWeak.Upgrade();
432 CHECK_NULL_VOID(newComponent);
433 subwindow->ShowPopup(newComponent, disableTouchEvent);
434 },
435 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowPopup");
436 }
437
CancelPopup(const std::string& id)438 bool SubwindowManager::CancelPopup(const std::string& id)
439 {
440 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "cancel popup enter");
441 auto subwindow = GetCurrentWindow();
442 if (subwindow) {
443 return subwindow->CancelPopup(id);
444 }
445 return false;
446 }
447
ShowMenu(const RefPtr<Component>& newComponent)448 void SubwindowManager::ShowMenu(const RefPtr<Component>& newComponent)
449 {
450 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show menu enter");
451 auto containerId = Container::CurrentId();
452 auto taskExecutor = Container::CurrentTaskExecutor();
453 CHECK_NULL_VOID(taskExecutor);
454 taskExecutor->PostTask(
455 [containerId, weakMenu = AceType::WeakClaim(AceType::RawPtr(newComponent))] {
456 auto menu = weakMenu.Upgrade();
457 CHECK_NULL_VOID(menu);
458 auto subwindow = SubwindowManager::GetInstance()->GetOrCreateSubwindow(containerId);
459 if (!subwindow) {
460 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
461 return;
462 }
463 subwindow->ShowMenu(menu);
464 },
465 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowMenu");
466 }
467
CloseMenu()468 void SubwindowManager::CloseMenu()
469 {
470 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close menu enter");
471 auto subwindow = GetCurrentWindow();
472 if (subwindow) {
473 subwindow->CloseMenu();
474 }
475 }
476
ClearMenu()477 void SubwindowManager::ClearMenu()
478 {
479 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear menu enter");
480 auto subwindow = GetCurrentWindow();
481 if (subwindow) {
482 subwindow->ClearMenu();
483 }
484 }
485
SetHotAreas(const std::vector<Rect>& rects, int32_t nodeId, int32_t instanceId)486 void SubwindowManager::SetHotAreas(const std::vector<Rect>& rects, int32_t nodeId, int32_t instanceId)
487 {
488 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set hot areas enter");
489 RefPtr<Subwindow> subwindow;
490 if (instanceId != -1) {
491 // get the subwindow which overlay node in, not current
492 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
493 } else {
494 subwindow = GetCurrentWindow();
495 }
496
497 if (subwindow) {
498 subwindow->SetHotAreas(rects, nodeId);
499 }
500 }
501
ShowDialogNG( const DialogProperties& dialogProps, std::function<void()>&& buildFunc)502 RefPtr<NG::FrameNode> SubwindowManager::ShowDialogNG(
503 const DialogProperties& dialogProps, std::function<void()>&& buildFunc)
504 {
505 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
506 auto containerId = Container::CurrentId();
507 auto subwindow = GetOrCreateSubwindow(containerId);
508 if (!subwindow) {
509 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
510 return nullptr;
511 }
512 return subwindow->ShowDialogNG(dialogProps, std::move(buildFunc));
513 }
ShowDialogNGWithNode(const DialogProperties& dialogProps, const RefPtr<NG::UINode>& customNode)514 RefPtr<NG::FrameNode> SubwindowManager::ShowDialogNGWithNode(const DialogProperties& dialogProps,
515 const RefPtr<NG::UINode>& customNode)
516 {
517 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog ng enter");
518 auto containerId = Container::CurrentId();
519 auto subwindow = GetOrCreateSubwindow(containerId);
520 if (!subwindow) {
521 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
522 return nullptr;
523 }
524 return subwindow->ShowDialogNGWithNode(dialogProps, customNode);
525 }
CloseDialogNG(const RefPtr<NG::FrameNode>& dialogNode)526 void SubwindowManager::CloseDialogNG(const RefPtr<NG::FrameNode>& dialogNode)
527 {
528 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close dialog ng enter");
529 auto containerId = Container::CurrentId();
530 auto subwindow = GetSubwindow(containerId);
531 if (!subwindow) {
532 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get subwindow failed.");
533 return;
534 }
535 return subwindow->CloseDialogNG(dialogNode);
536 }
537
OpenCustomDialogNG(const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)538 void SubwindowManager::OpenCustomDialogNG(const DialogProperties& dialogProps, std::function<void(int32_t)>&& callback)
539 {
540 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show customDialog ng enter");
541 auto containerId = Container::CurrentId();
542 auto subwindow = GetOrCreateSubwindow(containerId);
543 if (!subwindow) {
544 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
545 return;
546 }
547 return subwindow->OpenCustomDialogNG(dialogProps, std::move(callback));
548 }
549
CloseCustomDialogNG(int32_t dialogId)550 void SubwindowManager::CloseCustomDialogNG(int32_t dialogId)
551 {
552 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng enter");
553 for (auto &overlay : GetAllSubOverlayManager()) {
554 CHECK_NULL_VOID(overlay);
555 if (overlay->GetDialogMap().find(dialogId) != overlay->GetDialogMap().end()) {
556 return overlay->CloseCustomDialog(dialogId);
557 }
558 }
559 }
560
CloseCustomDialogNG(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)561 void SubwindowManager::CloseCustomDialogNG(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)>&& callback)
562 {
563 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close customDialog ng enter");
564 for (auto &overlay : GetAllSubOverlayManager()) {
565 CHECK_NULL_VOID(overlay);
566 overlay->CloseCustomDialog(node, std::move(callback));
567 }
568 }
569
UpdateCustomDialogNG( const WeakPtr<NG::UINode>& node, const PromptDialogAttr &dialogAttr, std::function<void(int32_t)>&& callback)570 void SubwindowManager::UpdateCustomDialogNG(
571 const WeakPtr<NG::UINode>& node, const PromptDialogAttr &dialogAttr, std::function<void(int32_t)>&& callback)
572 {
573 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "update customDialog ng enter");
574 DialogProperties dialogProperties = {
575 .autoCancel = dialogAttr.autoCancel,
576 .maskColor = dialogAttr.maskColor,
577 .isSysBlurStyle = false
578 };
579 if (dialogAttr.alignment.has_value()) {
580 dialogProperties.alignment = dialogAttr.alignment.value();
581 }
582 if (dialogAttr.offset.has_value()) {
583 dialogProperties.offset = dialogAttr.offset.value();
584 }
585 for (auto &overlay : GetAllSubOverlayManager()) {
586 if (overlay) {
587 overlay->UpdateCustomDialog(node, dialogProperties, std::move(callback));
588 }
589 }
590 }
591
HideDialogSubWindow(int32_t instanceId)592 void SubwindowManager::HideDialogSubWindow(int32_t instanceId)
593 {
594 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "hide dialog subwindow enter");
595 auto subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
596 CHECK_NULL_VOID(subwindow);
597 auto overlay = subwindow->GetOverlayManager();
598 CHECK_NULL_VOID(overlay);
599 if (overlay->GetDialogMap().size() == 0) {
600 subwindow->HideSubWindowNG();
601 } else {
602 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "fail to hide dialog subwindow, instanceId is %{public}d.", instanceId);
603 }
604 }
605
AddDialogSubwindow(int32_t instanceId, const RefPtr<Subwindow>& subwindow)606 void SubwindowManager::AddDialogSubwindow(int32_t instanceId, const RefPtr<Subwindow>& subwindow)
607 {
608 if (!subwindow) {
609 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add dialog subwindow failed, the subwindow is null.");
610 return;
611 }
612 std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
613 auto result = dialogSubwindowMap_.try_emplace(instanceId, subwindow);
614 if (!result.second) {
615 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "Add dialog failed of this instance %{public}d", instanceId);
616 return;
617 }
618 }
619
GetDialogSubwindow(int32_t instanceId)620 const RefPtr<Subwindow> SubwindowManager::GetDialogSubwindow(int32_t instanceId)
621 {
622 std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
623 auto result = dialogSubwindowMap_.find(instanceId);
624 if (result != dialogSubwindowMap_.end()) {
625 return result->second;
626 } else {
627 return nullptr;
628 }
629 }
630
SetCurrentDialogSubwindow(const RefPtr<Subwindow>& subwindow)631 void SubwindowManager::SetCurrentDialogSubwindow(const RefPtr<Subwindow>& subwindow)
632 {
633 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set current dialog subwindow enter");
634 std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
635 currentDialogSubwindow_ = subwindow;
636 }
637
GetCurrentDialogWindow()638 const RefPtr<Subwindow>& SubwindowManager::GetCurrentDialogWindow()
639 {
640 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "get current dialog window enter");
641 std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
642 return currentDialogSubwindow_;
643 }
644
GetOrCreateSubWindow()645 RefPtr<Subwindow> SubwindowManager::GetOrCreateSubWindow()
646 {
647 auto containerId = Container::CurrentId();
648 auto subwindow = GetDialogSubwindow(containerId);
649 if (!subwindow) {
650 subwindow = Subwindow::CreateSubwindow(containerId);
651 CHECK_NULL_RETURN(subwindow, nullptr);
652 AddDialogSubwindow(containerId, subwindow);
653 }
654 return subwindow;
655 }
656
GetOrCreateSystemSubWindow(int32_t containerId)657 RefPtr<Subwindow> SubwindowManager::GetOrCreateSystemSubWindow(int32_t containerId)
658 {
659 auto subwindow = GetSystemToastWindow(containerId);
660 if (!subwindow) {
661 subwindow = Subwindow::CreateSubwindow(containerId);
662 CHECK_NULL_RETURN(subwindow, nullptr);
663 AddSystemToastWindow(containerId, subwindow);
664 }
665 return subwindow;
666 }
667
ShowToastNG(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)668 void SubwindowManager::ShowToastNG(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
669 {
670 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show toast ng enter");
671 auto containerId = Container::CurrentId();
672 auto windowType = GetToastWindowType(containerId);
673 auto container = Container::GetContainer(containerId);
674 CHECK_NULL_VOID(container);
675 auto windowId = container->GetWindowId();
676 // Get the parent window ID before the asynchronous operation
677 auto mainWindowId = container->GetParentMainWindowId(windowId);
678 // for ability
679 auto taskExecutor = Container::CurrentTaskExecutor();
680 CHECK_NULL_VOID(taskExecutor);
681 taskExecutor->PostTask(
682 [containerId, toastInfo, callbackParam = std::move(callback), windowType, mainWindowId] {
683 auto subwindow = SubwindowManager::GetInstance()->GetOrCreateToastWindowNG(
684 containerId, windowType, mainWindowId);
685 CHECK_NULL_VOID(subwindow);
686 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before show toast : %{public}d", containerId);
687 subwindow->ShowToast(toastInfo, std::move(const_cast<std::function<void(int32_t)>&&>(callbackParam)));
688 },
689 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowToastNG");
690 }
691
GetToastWindowType(int32_t instanceId)692 ToastWindowType SubwindowManager::GetToastWindowType(int32_t instanceId)
693 {
694 auto parentContainer = Container::GetContainer(instanceId);
695 CHECK_NULL_RETURN(parentContainer, ToastWindowType::TOAST_IN_TYPE_TOAST);
696 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "GetToastWindowType instanceId: %{public}d", instanceId);
697 // toast window should be TOAST_IN_TYPE_APP_SUB_WINDOW when parent window is dialog window.
698 if (parentContainer->IsMainWindow() || parentContainer->IsSubWindow() ||
699 parentContainer->IsDialogWindow()) {
700 return ToastWindowType::TOAST_IN_TYPE_APP_SUB_WINDOW;
701 } else if (parentContainer->IsScenceBoardWindow()) {
702 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_FLOAT;
703 } else if (parentContainer->IsSystemWindow()) {
704 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_SUB_WINDOW;
705 } else if (parentContainer->IsUIExtensionWindow()) {
706 if (parentContainer->IsHostMainWindow() || parentContainer->IsHostSubWindow() ||
707 parentContainer->IsHostDialogWindow()) {
708 return ToastWindowType::TOAST_IN_TYPE_APP_SUB_WINDOW;
709 } else if (parentContainer->IsHostSceneBoardWindow()) {
710 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_FLOAT;
711 } else if (parentContainer->IsHostSystemWindow()) {
712 return ToastWindowType::TOAST_IN_TYPE_SYSTEM_SUB_WINDOW;
713 }
714 }
715 return ToastWindowType::TOAST_IN_TYPE_TOAST;
716 }
717
ShowToast(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)718 void SubwindowManager::ShowToast(const NG::ToastInfo& toastInfo, std::function<void(int32_t)>&& callback)
719 {
720 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show toast enter");
721 auto containerId = Container::CurrentId();
722 auto isTopMost = toastInfo.showMode == NG::ToastShowMode::TOP_MOST;
723 // for pa service
724 if ((isTopMost && containerId >= MIN_PA_SERVICE_ID && containerId < MIN_SUBCONTAINER_ID) ||
725 (!isTopMost && containerId >= MIN_PA_SERVICE_ID) || containerId < 0) {
726 auto subwindow = toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST ?
727 GetOrCreateSystemSubWindow(containerId) : GetOrCreateSubWindow();
728 CHECK_NULL_VOID(subwindow);
729 subwindow->SetIsSystemTopMost(toastInfo.showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
730 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before show toast");
731 subwindow->ShowToast(toastInfo, std::move(callback));
732 } else {
733 // for ability
734 auto parentContainer = Container::GetContainer(containerId);
735 // in scenceboard, system_top_most needs to go the old way,
736 // default and top_most need to go showToastNG
737 if (toastInfo.showMode == NG::ToastShowMode::TOP_MOST ||
738 (parentContainer && parentContainer->IsScenceBoardWindow() &&
739 toastInfo.showMode != NG::ToastShowMode::SYSTEM_TOP_MOST)) {
740 ShowToastNG(toastInfo, std::move(callback));
741 return;
742 }
743 auto taskExecutor = Container::CurrentTaskExecutor();
744 CHECK_NULL_VOID(taskExecutor);
745 taskExecutor->PostTask(
746 [containerId, toastInfo, callbackParam = std::move(callback)] {
747 auto subwindow = SubwindowManager::GetInstance()->GetOrCreateToastWindow(containerId, toastInfo.showMode);
748 CHECK_NULL_VOID(subwindow);
749 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before show toast : %{public}d", containerId);
750 subwindow->ShowToast(toastInfo, std::move(const_cast<std::function<void(int32_t)>&&>(callbackParam)));
751 },
752 TaskExecutor::TaskType::PLATFORM, "ArkUISubwindowShowToast");
753 }
754 }
755
CloseToast( const int32_t toastId, const NG::ToastShowMode& showMode, std::function<void(int32_t)>&& callback)756 void SubwindowManager::CloseToast(
757 const int32_t toastId, const NG::ToastShowMode& showMode, std::function<void(int32_t)>&& callback)
758 {
759 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "close toast enter");
760 auto containerId = Container::CurrentId();
761
762 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
763 // for pa service
764 auto subwindow = showMode == NG::ToastShowMode::SYSTEM_TOP_MOST ?
765 GetSystemToastWindow(containerId) : GetDialogSubwindow(containerId);
766 CHECK_NULL_VOID(subwindow);
767 subwindow->SetIsSystemTopMost(showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
768 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before close toast");
769 subwindow->CloseToast(toastId, std::move(callback));
770 } else {
771 // for ability
772 if (showMode == NG::ToastShowMode::TOP_MOST) {
773 auto subwindow = GetToastSubwindow(containerId);
774 subwindow->CloseToast(toastId, std::move(callback));
775 return;
776 }
777 auto manager = SubwindowManager::GetInstance();
778 CHECK_NULL_VOID(manager);
779 auto subwindow = showMode == NG::ToastShowMode::SYSTEM_TOP_MOST ?
780 GetSystemToastWindow(containerId) : GetSubwindow(containerId);
781 CHECK_NULL_VOID(subwindow);
782 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "before close toast : %{public}d", containerId);
783 subwindow->CloseToast(toastId, std::move(callback));
784 }
785 }
786
GetOrCreateToastWindow(int32_t containerId, const NG::ToastShowMode& showMode)787 RefPtr<Subwindow> SubwindowManager::GetOrCreateToastWindow(int32_t containerId, const NG::ToastShowMode& showMode)
788 {
789 auto isSystemTopMost = (showMode == NG::ToastShowMode::SYSTEM_TOP_MOST);
790 RefPtr<Subwindow> subwindow = nullptr;
791 if (isSystemTopMost) {
792 subwindow = GetSystemToastWindow(containerId);
793 } else {
794 subwindow = GetSubwindow(containerId);
795 }
796
797 if (!subwindow) {
798 subwindow = Subwindow::CreateSubwindow(containerId);
799 if (!subwindow) {
800 TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "create sub window failed");
801 return nullptr;
802 }
803 subwindow->SetIsSystemTopMost(isSystemTopMost);
804 subwindow->SetAboveApps(showMode == NG::ToastShowMode::TOP_MOST);
805 if (isSystemTopMost) {
806 AddSystemToastWindow(containerId, subwindow);
807 } else {
808 AddSubwindow(containerId, subwindow);
809 }
810 }
811
812 return subwindow;
813 }
814
GetOrCreateToastWindowNG(int32_t containerId, const ToastWindowType& windowType, uint32_t mainWindowId)815 RefPtr<Subwindow> SubwindowManager::GetOrCreateToastWindowNG(int32_t containerId,
816 const ToastWindowType& windowType, uint32_t mainWindowId)
817 {
818 RefPtr<Subwindow> subwindow = GetToastSubwindow(containerId);
819 if (!subwindow) {
820 subwindow = Subwindow::CreateSubwindow(containerId);
821 if (!subwindow) {
822 TAG_LOGE(AceLogTag::ACE_SUB_WINDOW, "create toast subwindow failed");
823 return nullptr;
824 }
825 subwindow->SetToastWindowType(windowType);
826 subwindow->SetMainWindowId(mainWindowId);
827 AddToastSubwindow(containerId, subwindow);
828 }
829 return subwindow;
830 }
831
ClearToastInSubwindow()832 void SubwindowManager::ClearToastInSubwindow()
833 {
834 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear toast in subwindow enter");
835 auto containerId = Container::CurrentId();
836 // Get active container when current instanceid is less than 0
837 if (containerId < 0) {
838 auto container = Container::GetActive();
839 if (container) {
840 containerId = container->GetInstanceId();
841 }
842 }
843 RefPtr<Subwindow> subwindow;
844 // The main window does not need to clear Toast
845 if (containerId != -1 && containerId < MIN_SUBCONTAINER_ID) {
846 // get the subwindow which overlay node in, not current
847 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
848 GetParentContainerId(containerId) : containerId;
849 subwindow = GetToastSubwindow(parentContainerId);
850 }
851 if (subwindow) {
852 subwindow->ClearToast();
853 }
854 }
855
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)856 void SubwindowManager::ShowDialog(const std::string& title, const std::string& message,
857 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& napiCallback,
858 const std::set<std::string>& dialogCallbacks)
859 {
860 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog enter");
861 auto containerId = Container::CurrentId();
862 // Get active container when current instanceid is less than 0
863 if (containerId < 0) {
864 auto container = Container::GetActive();
865 if (container) {
866 containerId = container->GetInstanceId();
867 }
868 }
869 // for pa service
870 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
871 auto subwindow = GetOrCreateSubWindow();
872 CHECK_NULL_VOID(subwindow);
873 subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
874 // for ability
875 } else {
876 auto subwindow = GetOrCreateSubwindow(containerId);
877 if (!subwindow) {
878 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
879 return;
880 }
881 subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
882 }
883 }
884
ShowDialog(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons, std::function<void(int32_t, int32_t)>&& napiCallback, const std::set<std::string>& dialogCallbacks)885 void SubwindowManager::ShowDialog(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
886 std::function<void(int32_t, int32_t)>&& napiCallback, const std::set<std::string>& dialogCallbacks)
887 {
888 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show dialog enter");
889 auto containerId = Container::CurrentId();
890 // Get active container when current instanceid is less than 0
891 if (containerId < 0) {
892 auto container = Container::GetActive();
893 if (container) {
894 containerId = container->GetInstanceId();
895 }
896 }
897 // for pa service
898 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
899 auto subwindow = GetOrCreateSubWindow();
900 CHECK_NULL_VOID(subwindow);
901 subwindow->ShowDialog(dialogAttr, buttons, std::move(napiCallback), dialogCallbacks);
902 // for ability
903 } else {
904 auto subwindow = GetOrCreateSubwindow(containerId);
905 if (!subwindow) {
906 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
907 return;
908 }
909 subwindow->ShowDialog(dialogAttr, buttons, std::move(napiCallback), dialogCallbacks);
910 }
911 }
912
ShowActionMenu( const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)913 void SubwindowManager::ShowActionMenu(
914 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
915 {
916 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "show action menu enter");
917 auto containerId = Container::CurrentId();
918 // Get active container when current instanceid is less than 0
919 if (containerId < 0) {
920 auto container = Container::GetActive();
921 if (container) {
922 containerId = container->GetInstanceId();
923 }
924 }
925 // for pa service
926 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
927 auto subwindow = GetOrCreateSubWindow();
928 CHECK_NULL_VOID(subwindow);
929 subwindow->ShowActionMenu(title, button, std::move(callback));
930 // for ability
931 } else {
932 auto subwindow = GetOrCreateSubwindow(containerId);
933 if (!subwindow) {
934 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
935 return;
936 }
937 subwindow->ShowActionMenu(title, button, std::move(callback));
938 }
939 }
940
CloseDialog(int32_t instanceId)941 void SubwindowManager::CloseDialog(int32_t instanceId)
942 {
943 auto subwindow = GetDialogSubwindow(instanceId);
944 if (!subwindow) {
945 subwindow = GetSubwindow(instanceId);
946 if (subwindow) {
947 subwindow->Close();
948 return;
949 }
950 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get dialog subwindow failed.");
951 return;
952 }
953 auto subContainerId = GetSubContainerId(instanceId);
954 if (subContainerId > -1) {
955 subwindow->CloseDialog(subContainerId);
956 }
957 }
958
OpenCustomDialog(const PromptDialogAttr &dialogAttr, std::function<void(int32_t)> &&callback)959 void SubwindowManager::OpenCustomDialog(const PromptDialogAttr &dialogAttr, std::function<void(int32_t)> &&callback)
960 {
961 PromptDialogAttr tmpPromptAttr = dialogAttr;
962 tmpPromptAttr.showInSubWindow = false;
963 auto containerId = Container::CurrentId();
964 // for pa service
965 TAG_LOGI(AceLogTag::ACE_SUB_WINDOW, "container %{public}d open the custom dialog", containerId);
966 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
967 auto subwindow = GetOrCreateSubWindow();
968 CHECK_NULL_VOID(subwindow);
969 subwindow->OpenCustomDialog(tmpPromptAttr, std::move(callback));
970 // for ability
971 } else {
972 auto subwindow = GetOrCreateSubwindow(containerId);
973 if (!subwindow) {
974 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
975 return;
976 }
977 subwindow->OpenCustomDialog(tmpPromptAttr, std::move(callback));
978 }
979 return;
980 }
981
CloseCustomDialog(const int32_t dialogId)982 void SubwindowManager::CloseCustomDialog(const int32_t dialogId)
983 {
984 auto containerId = Container::CurrentId();
985 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "CloseCustomDialog dialogId = %{public}d, containerId = %{public}d.",
986 dialogId, containerId);
987 auto subwindow = GetDialogSubwindow(containerId);
988 if (!subwindow) {
989 return;
990 }
991 subwindow->CloseCustomDialog(dialogId);
992 return;
993 }
994
CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)> &&callback)995 void SubwindowManager::CloseCustomDialog(const WeakPtr<NG::UINode>& node, std::function<void(int32_t)> &&callback)
996 {
997 auto containerId = Container::CurrentId();
998 auto subwindow = GetDialogSubwindow(containerId);
999 if (!subwindow) {
1000 return;
1001 }
1002 subwindow->CloseCustomDialog(node, std::move(callback));
1003 return;
1004 }
1005
HideSubWindowNG()1006 void SubwindowManager::HideSubWindowNG()
1007 {
1008 RefPtr<Subwindow> subwindow;
1009 auto container = Container::Current();
1010 CHECK_NULL_VOID(container);
1011 if (container->IsDialogContainer()) {
1012 subwindow = GetCurrentDialogWindow();
1013 } else {
1014 subwindow = GetCurrentWindow();
1015 }
1016 if (subwindow) {
1017 subwindow->HideSubWindowNG();
1018 }
1019 }
1020
HideToastSubWindowNG()1021 void SubwindowManager::HideToastSubWindowNG()
1022 {
1023 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "hide toast subwindow enter");
1024 RefPtr<Subwindow> subwindow;
1025 auto container = Container::Current();
1026 auto containerId = Container::CurrentId();
1027 CHECK_NULL_VOID(container);
1028 if (container->IsDialogContainer()) {
1029 subwindow = GetCurrentDialogWindow();
1030 } else if (containerId != -1) {
1031 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
1032 GetParentContainerId(containerId) : containerId;
1033 subwindow = GetToastSubwindow(parentContainerId);
1034 }
1035 if (subwindow) {
1036 subwindow->HideSubWindowNG();
1037 }
1038 }
1039
RequestFocusSubwindow(int32_t instanceId)1040 void SubwindowManager::RequestFocusSubwindow(int32_t instanceId)
1041 {
1042 RefPtr<Subwindow> subwindow;
1043 if (instanceId != -1) {
1044 // get the subwindow which overlay node in, not current
1045 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
1046 } else {
1047 subwindow = GetCurrentWindow();
1048 }
1049 if (subwindow) {
1050 subwindow->RequestFocus();
1051 }
1052 }
1053
GetShown()1054 bool SubwindowManager::GetShown()
1055 {
1056 auto containerId = Container::CurrentId();
1057 auto subwindow = GetOrCreateSubwindow(containerId);
1058 if (!subwindow) {
1059 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW, "get or create subwindow failed");
1060 return false;
1061 }
1062 return subwindow->GetShown();
1063 }
1064
ResizeWindowForFoldStatus(int32_t parentContainerId)1065 void SubwindowManager::ResizeWindowForFoldStatus(int32_t parentContainerId)
1066 {
1067 auto containerId = Container::CurrentId();
1068 auto subwindow = parentContainerId < 0 ? GetDialogSubwindow(parentContainerId) : GetToastSubwindow(containerId);
1069 if (!subwindow) {
1070 TAG_LOGW(AceLogTag::ACE_SUB_WINDOW,
1071 "Get Subwindow error, containerId = %{public}d, parentContainerId = %{public}d", containerId,
1072 parentContainerId);
1073 return;
1074 }
1075 subwindow->ResizeWindowForFoldStatus(parentContainerId);
1076 }
1077
MarkDirtyDialogSafeArea()1078 void SubwindowManager::MarkDirtyDialogSafeArea()
1079 {
1080 auto containerId = Container::CurrentId();
1081 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(containerId);
1082 CHECK_NULL_VOID(subwindow);
1083 if (subwindow) {
1084 subwindow->MarkDirtyDialogSafeArea();
1085 }
1086 subwindow = GetToastSubwindow(containerId);
1087 if (subwindow) {
1088 subwindow->MarkDirtyDialogSafeArea();
1089 }
1090 }
1091
HideSystemTopMostWindow()1092 void SubwindowManager::HideSystemTopMostWindow()
1093 {
1094 auto containerId = Container::CurrentId();
1095 if (containerId < 0) {
1096 auto container = Container::GetActive();
1097 if (container) {
1098 containerId = container->GetInstanceId();
1099 }
1100 }
1101 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
1102 GetParentContainerId(containerId) : containerId;
1103 auto subwindow = GetSystemToastWindow(parentContainerId);
1104 if (subwindow) {
1105 subwindow->HideSubWindowNG();
1106 } else {
1107 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "can not find systemTopMost window when hide window");
1108 }
1109 }
1110
ClearToastInSystemSubwindow()1111 void SubwindowManager::ClearToastInSystemSubwindow()
1112 {
1113 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "clear toast in system subwindow enter");
1114 auto containerId = Container::CurrentId();
1115 if (containerId < 0) {
1116 auto container = Container::GetActive();
1117 if (container) {
1118 containerId = container->GetInstanceId();
1119 }
1120 }
1121 auto parentContainerId = containerId >= MIN_SUBCONTAINER_ID ?
1122 GetParentContainerId(containerId) : containerId;
1123 auto subwindow = GetSystemToastWindow(parentContainerId);
1124 if (subwindow) {
1125 subwindow->ClearToast();
1126 } else {
1127 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "can not find systemTopMost window when clear system toast");
1128 }
1129 }
OnWindowSizeChanged(int32_t instanceId, Rect windowRect, WindowSizeChangeReason reason)1130 void SubwindowManager::OnWindowSizeChanged(int32_t instanceId, Rect windowRect, WindowSizeChangeReason reason)
1131 {
1132 auto container = Container::GetContainer(instanceId);
1133 CHECK_NULL_VOID(container);
1134 if (!container->IsUIExtensionWindow() || uiExtensionWindowRect_ == windowRect) {
1135 return;
1136 }
1137 auto subContainer = Container::GetContainer(GetSubContainerId(instanceId));
1138 CHECK_NULL_VOID(subContainer);
1139 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(subContainer->GetPipelineContext());
1140 CHECK_NULL_VOID(pipeline);
1141 auto overlayManager = pipeline->GetOverlayManager();
1142 CHECK_NULL_VOID(overlayManager);
1143 overlayManager->OnUIExtensionWindowSizeChange();
1144 uiExtensionWindowRect_ = windowRect;
1145 }
1146
GetSubwindowDialogNodeWithExistContent(const RefPtr<NG::UINode>& node)1147 RefPtr<NG::FrameNode> SubwindowManager::GetSubwindowDialogNodeWithExistContent(const RefPtr<NG::UINode>& node)
1148 {
1149 for (auto &overlay : GetAllSubOverlayManager()) {
1150 CHECK_NULL_RETURN(overlay, nullptr);
1151 auto dialogNode = overlay->GetDialogNodeWithExistContent(node);
1152 if (dialogNode) {
1153 return dialogNode;
1154 }
1155 }
1156 return nullptr;
1157 }
1158
SetRect(const NG::RectF& rect, int32_t instanceId)1159 void SubwindowManager::SetRect(const NG::RectF& rect, int32_t instanceId)
1160 {
1161 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "set subwindow rect enter");
1162 RefPtr<Subwindow> subwindow;
1163 if (instanceId != -1) {
1164 // get the subwindow which overlay node in, not current
1165 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
1166 } else {
1167 subwindow = GetCurrentWindow();
1168 }
1169
1170 if (subwindow) {
1171 subwindow->SetRect(rect);
1172 } else {
1173 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "can not get subwindow, set rect failed");
1174 }
1175 }
1176
IsFreeMultiWindow(int32_t instanceId) const1177 bool SubwindowManager::IsFreeMultiWindow(int32_t instanceId) const
1178 {
1179 auto parentContainerId = instanceId >= MIN_SUBCONTAINER_ID
1180 ? SubwindowManager::GetInstance()->GetParentContainerId(instanceId)
1181 : instanceId;
1182 auto subWindow = SubwindowManager::GetInstance()->GetSubwindow(parentContainerId);
1183 CHECK_NULL_RETURN(subWindow, false);
1184 return subWindow->IsFreeMultiWindow();
1185 }
1186
GetAllSubOverlayManager()1187 const std::vector<RefPtr<NG::OverlayManager>> SubwindowManager::GetAllSubOverlayManager()
1188 {
1189 std::lock_guard<std::mutex> lock(subwindowMutex_);
1190 std::vector<RefPtr<NG::OverlayManager>> subOverlayManager;
1191 subOverlayManager.reserve(subwindowMap_.size());
1192 auto iter = subwindowMap_.begin();
1193 while (iter != subwindowMap_.end()) {
1194 auto subwindow = iter->second;
1195 if (subwindow) {
1196 subOverlayManager.push_back(subwindow->GetOverlayManager());
1197 }
1198 iter++;
1199 }
1200 return subOverlayManager;
1201 }
1202 } // namespace OHOS::Ace
1203