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