1 /*
2 * Copyright (c) 2022 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 <memory>
19 #include <mutex>
20
21 #include "unistd.h"
22
23 #include "base/geometry/rect.h"
24 #include "base/log/log.h"
25 #include "base/memory/ace_type.h"
26 #include "core/common/ace_page.h"
27 #include "core/common/container.h"
28
29 namespace OHOS::Ace {
30
31 std::mutex SubwindowManager::instanceMutex_;
32 std::shared_ptr<SubwindowManager> SubwindowManager::instance_;
33
GetInstance()34 std::shared_ptr<SubwindowManager> SubwindowManager::GetInstance()
35 {
36 std::lock_guard<std::mutex> lock(instanceMutex_);
37 if (!instance_) {
38 instance_ = std::make_shared<SubwindowManager>();
39 }
40 return instance_;
41 }
42
AddContainerId(uint32_t windowId,int32_t containerId)43 void SubwindowManager::AddContainerId(uint32_t windowId, int32_t containerId)
44 {
45 std::lock_guard<std::mutex> lock(mutex_);
46 auto result = containerMap_.try_emplace(windowId, containerId);
47 if (!result.second) {
48 LOGW("Already have container of this windowId, windowId: %{public}u", windowId);
49 }
50 }
51
RemoveContainerId(uint32_t windowId)52 void SubwindowManager::RemoveContainerId(uint32_t windowId)
53 {
54 std::lock_guard<std::mutex> lock(mutex_);
55 containerMap_.erase(windowId);
56 }
57
GetContainerId(uint32_t windowId)58 int32_t SubwindowManager::GetContainerId(uint32_t windowId)
59 {
60 std::lock_guard<std::mutex> lock(mutex_);
61 auto result = containerMap_.find(windowId);
62 if (result != containerMap_.end()) {
63 return result->second;
64 } else {
65 return -1;
66 }
67 }
68
AddParentContainerId(int32_t containerId,int32_t parentContainerId)69 void SubwindowManager::AddParentContainerId(int32_t containerId, int32_t parentContainerId)
70 {
71 LOGI("Container id is %{public}d, parent id is %{public}d.", containerId, parentContainerId);
72 std::lock_guard<std::mutex> lock(parentMutex_);
73 auto result = parentContainerMap_.try_emplace(containerId, parentContainerId);
74 if (!result.second) {
75 LOGW("Already have container of this %{public}d", containerId);
76 }
77 }
78
RemoveParentContainerId(int32_t containerId)79 void SubwindowManager::RemoveParentContainerId(int32_t containerId)
80 {
81 std::lock_guard<std::mutex> lock(parentMutex_);
82 parentContainerMap_.erase(containerId);
83 }
84
GetParentContainerId(int32_t containerId)85 int32_t SubwindowManager::GetParentContainerId(int32_t containerId)
86 {
87 std::lock_guard<std::mutex> lock(parentMutex_);
88 auto result = parentContainerMap_.find(containerId);
89 if (result != parentContainerMap_.end()) {
90 return result->second;
91 } else {
92 return 0;
93 }
94 }
95
AddSubwindow(int32_t instanceId,RefPtr<Subwindow> subwindow)96 void SubwindowManager::AddSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
97 {
98 if (!subwindow) {
99 LOGE("Add subwindow failed, the subwindow is null.");
100 return;
101 }
102 LOGI("Add subwindow into map, instanceId is %{public}d, subwindow id is %{public}d.", instanceId,
103 subwindow->GetSubwindowId());
104 std::lock_guard<std::mutex> lock(subwindowMutex_);
105 auto result = subwindowMap_.try_emplace(instanceId, subwindow);
106 if (!result.second) {
107 LOGE("Add failed of this instance %{public}d", instanceId);
108 return;
109 }
110 LOGI("Add subwindow success of this instance %{public}d.", instanceId);
111 }
112
RemoveSubwindow(int32_t instanceId)113 void SubwindowManager::RemoveSubwindow(int32_t instanceId)
114 {
115 LOGI("Remove subwindow of this instance %{public}d", instanceId);
116 std::lock_guard<std::mutex> lock(subwindowMutex_);
117 int res = static_cast<int>(subwindowMap_.erase(instanceId));
118 if (res == 0) {
119 LOGW("Remove subwindow of instance %{public}d failed.", instanceId);
120 }
121 }
122
GetSubwindow(int32_t instanceId)123 const RefPtr<Subwindow> SubwindowManager::GetSubwindow(int32_t instanceId)
124 {
125 LOGI("Get subwindow of instance %{public}d.", instanceId);
126 std::lock_guard<std::mutex> lock(subwindowMutex_);
127 auto result = subwindowMap_.find(instanceId);
128 if (result != subwindowMap_.end()) {
129 return result->second;
130 } else {
131 return nullptr;
132 }
133 }
134
SetCurrentSubwindowName(const std::string & currentSubwindowName)135 void SubwindowManager::SetCurrentSubwindowName(const std::string& currentSubwindowName)
136 {
137 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
138 currentSubwindowName_ = currentSubwindowName;
139 }
140
GetCurrentSubWindowName()141 std::string SubwindowManager::GetCurrentSubWindowName()
142 {
143 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
144 return currentSubwindowName_;
145 }
146
SetCurrentSubwindow(const RefPtr<Subwindow> & subwindow)147 void SubwindowManager::SetCurrentSubwindow(const RefPtr<Subwindow>& subwindow)
148 {
149 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
150 currentSubwindow_ = subwindow;
151
152 if (onShowMenuCallback_) {
153 RegisterOnShowMenu(onShowMenuCallback_);
154 }
155 if (onHideMenuCallback_) {
156 RegisterOnHideMenu(onHideMenuCallback_);
157 }
158 }
159
GetCurrentWindow()160 const RefPtr<Subwindow>& SubwindowManager::GetCurrentWindow()
161 {
162 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
163 return currentSubwindow_;
164 }
165
GetParentWindowRect()166 Rect SubwindowManager::GetParentWindowRect()
167 {
168 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
169 Rect rect;
170 CHECK_NULL_RETURN(currentSubwindow_, rect);
171 return currentSubwindow_->GetParentWindowRect();
172 }
173
ShowMenuNG(const RefPtr<NG::FrameNode> & menuNode,int32_t targetId,const NG::OffsetF & offset,bool isAboveApps)174 void SubwindowManager::ShowMenuNG(const RefPtr<NG::FrameNode>& menuNode, int32_t targetId,
175 const NG::OffsetF& offset, bool isAboveApps)
176 {
177 auto containerId = Container::CurrentId();
178 auto subwindow = GetSubwindow(containerId);
179 if (!subwindow) {
180 subwindow = Subwindow::CreateSubwindow(containerId);
181 subwindow->InitContainer();
182 AddSubwindow(containerId, subwindow);
183 }
184 subwindow->ShowMenuNG(menuNode, targetId, offset);
185 }
186
HideMenuNG(const RefPtr<NG::FrameNode> & menu,int32_t targetId)187 void SubwindowManager::HideMenuNG(const RefPtr<NG::FrameNode>& menu, int32_t targetId)
188 {
189 auto subwindow = GetCurrentWindow();
190 if (subwindow) {
191 subwindow->HideMenuNG(menu, targetId);
192 }
193 }
194
HideMenuNG()195 void SubwindowManager::HideMenuNG()
196 {
197 auto subwindow = GetCurrentWindow();
198 if (subwindow) {
199 subwindow->HideMenuNG();
200 }
201 }
202
ClearMenuNG(int32_t instanceId,bool inWindow)203 void SubwindowManager::ClearMenuNG(int32_t instanceId, bool inWindow)
204 {
205 RefPtr<Subwindow> subwindow;
206 if (instanceId != -1) {
207 // get the subwindow which overlay node in, not current
208 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
209 } else {
210 subwindow = GetCurrentWindow();
211 }
212 if (subwindow) {
213 subwindow->ClearMenuNG(inWindow);
214 }
215 }
216
ShowPopupNG(int32_t targetId,const NG::PopupInfo & popupInfo)217 void SubwindowManager::ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo)
218 {
219 auto containerId = Container::CurrentId();
220 auto manager = SubwindowManager::GetInstance();
221 CHECK_NULL_VOID(manager);
222 auto subwindow = manager->GetSubwindow(containerId);
223 if (!subwindow) {
224 auto taskExecutor = Container::CurrentTaskExecutor();
225 CHECK_NULL_VOID(taskExecutor);
226 taskExecutor->PostTask(
227 [containerId, targetId, popupInfo, manager] {
228 LOGI("Subwindow is null, add a new one.");
229 auto subwindow = Subwindow::CreateSubwindow(containerId);
230 subwindow->InitContainer();
231 manager->AddSubwindow(containerId, subwindow);
232 subwindow->ShowPopupNG(targetId, popupInfo);
233 },
234 TaskExecutor::TaskType::PLATFORM);
235 } else {
236 subwindow->ShowPopupNG(targetId, popupInfo);
237 }
238 }
239
HidePopupNG(int32_t targetId,int32_t instanceId)240 void SubwindowManager::HidePopupNG(int32_t targetId, int32_t instanceId)
241 {
242 RefPtr<Subwindow> subwindow;
243 if (instanceId != -1) {
244 // get the subwindow which overlay node in, not current
245 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
246 } else {
247 subwindow = GetCurrentWindow();
248 }
249
250 if (subwindow) {
251 subwindow->HidePopupNG(targetId);
252 }
253 }
254
ShowPopup(const RefPtr<Component> & newComponent,bool disableTouchEvent)255 void SubwindowManager::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
256 {
257 auto containerId = Container::CurrentId();
258 auto taskExecutor = Container::CurrentTaskExecutor();
259 CHECK_NULL_VOID(taskExecutor);
260 taskExecutor->PostTask(
261 [containerId, newComponentWeak = WeakPtr<Component>(newComponent), disableTouchEvent] {
262 auto manager = SubwindowManager::GetInstance();
263 CHECK_NULL_VOID(manager);
264 auto subwindow = manager->GetSubwindow(containerId);
265 if (!subwindow) {
266 LOGI("Subwindow is null, add a new one.");
267 subwindow = Subwindow::CreateSubwindow(containerId);
268 subwindow->InitContainer();
269 manager->AddSubwindow(containerId, subwindow);
270 }
271 auto newComponent = newComponentWeak.Upgrade();
272 CHECK_NULL_VOID(newComponent);
273 subwindow->ShowPopup(newComponent, disableTouchEvent);
274 },
275 TaskExecutor::TaskType::PLATFORM);
276 }
277
CancelPopup(const std::string & id)278 bool SubwindowManager::CancelPopup(const std::string& id)
279 {
280 auto subwindow = GetCurrentWindow();
281 if (subwindow) {
282 return subwindow->CancelPopup(id);
283 }
284 return false;
285 }
286
ShowMenu(const RefPtr<Component> & newComponent)287 void SubwindowManager::ShowMenu(const RefPtr<Component>& newComponent)
288 {
289 auto containerId = Container::CurrentId();
290 auto taskExecutor = Container::CurrentTaskExecutor();
291 CHECK_NULL_VOID(taskExecutor);
292 taskExecutor->PostTask(
293 [containerId, weakMenu = AceType::WeakClaim(AceType::RawPtr(newComponent))] {
294 auto manager = SubwindowManager::GetInstance();
295 CHECK_NULL_VOID(manager);
296 auto menu = weakMenu.Upgrade();
297 CHECK_NULL_VOID(menu);
298 auto subwindow = manager->GetSubwindow(containerId);
299 if (!subwindow) {
300 LOGI("Subwindow is null, add a new one.");
301 subwindow = Subwindow::CreateSubwindow(containerId);
302 subwindow->InitContainer();
303 manager->AddSubwindow(containerId, subwindow);
304 }
305 subwindow->ShowMenu(menu);
306 },
307 TaskExecutor::TaskType::PLATFORM);
308 }
309
CloseMenu()310 void SubwindowManager::CloseMenu()
311 {
312 auto subwindow = GetCurrentWindow();
313 if (subwindow) {
314 subwindow->CloseMenu();
315 }
316 }
317
ClearMenu()318 void SubwindowManager::ClearMenu()
319 {
320 auto subwindow = GetCurrentWindow();
321 if (subwindow) {
322 subwindow->ClearMenu();
323 }
324 }
325
SetHotAreas(const std::vector<Rect> & rects,int32_t overlayId,int32_t instanceId)326 void SubwindowManager::SetHotAreas(const std::vector<Rect>& rects, int32_t overlayId, int32_t instanceId)
327 {
328 RefPtr<Subwindow> subwindow;
329 if (instanceId != -1) {
330 // get the subwindow which overlay node in, not current
331 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
332 } else {
333 subwindow = GetCurrentWindow();
334 }
335
336 if (subwindow) {
337 subwindow->SetHotAreas(rects, overlayId);
338 }
339 }
340
ShowDialogNG(const DialogProperties & dialogProps,std::function<void ()> && buildFunc)341 RefPtr<NG::FrameNode> SubwindowManager::ShowDialogNG(
342 const DialogProperties& dialogProps, std::function<void()>&& buildFunc)
343 {
344 auto containerId = Container::CurrentId();
345 auto subwindow = GetSubwindow(containerId);
346 if (!subwindow) {
347 LOGI("Subwindow is null, add a new one.");
348 subwindow = Subwindow::CreateSubwindow(containerId);
349 subwindow->InitContainer();
350 AddSubwindow(containerId, subwindow);
351 }
352 return subwindow->ShowDialogNG(dialogProps, std::move(buildFunc));
353 }
354
AddDialogSubwindow(int32_t instanceId,const RefPtr<Subwindow> & subwindow)355 void SubwindowManager::AddDialogSubwindow(int32_t instanceId, const RefPtr<Subwindow>& subwindow)
356 {
357 if (!subwindow) {
358 LOGE("Add dialog subwindow failed, the subwindow is null.");
359 return;
360 }
361 LOGI("Add dialog subwindow into map, instanceId is %{public}d, subwindow id is %{public}d.", instanceId,
362 subwindow->GetSubwindowId());
363 std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
364 auto result = dialogSubwindowMap_.try_emplace(instanceId, subwindow);
365 if (!result.second) {
366 LOGE("Add dialog failed of this instance %{public}d", instanceId);
367 return;
368 }
369 LOGI("Add dialog subwindow success of this instance %{public}d.", instanceId);
370 }
371
GetDialogSubwindow(int32_t instanceId)372 const RefPtr<Subwindow> SubwindowManager::GetDialogSubwindow(int32_t instanceId)
373 {
374 LOGI("Get dialog subwindow of instance %{public}d.", instanceId);
375 std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
376 auto result = dialogSubwindowMap_.find(instanceId);
377 if (result != dialogSubwindowMap_.end()) {
378 return result->second;
379 } else {
380 return nullptr;
381 }
382 }
383
SetCurrentDialogSubwindow(const RefPtr<Subwindow> & subwindow)384 void SubwindowManager::SetCurrentDialogSubwindow(const RefPtr<Subwindow>& subwindow)
385 {
386 std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
387 currentDialogSubwindow_ = subwindow;
388 }
389
GetCurrentDialogWindow()390 const RefPtr<Subwindow>& SubwindowManager::GetCurrentDialogWindow()
391 {
392 std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
393 return currentDialogSubwindow_;
394 }
395
GetOrCreateSubWindow()396 RefPtr<Subwindow> SubwindowManager::GetOrCreateSubWindow()
397 {
398 auto containerId = Container::CurrentId();
399 LOGI("SubwindowManager::GetOrCreateSubWindow containerId = %{public}d.", containerId);
400 auto subwindow = GetDialogSubwindow(containerId);
401 if (!subwindow) {
402 LOGI("Subwindow is null, add a new one.");
403 subwindow = Subwindow::CreateSubwindow(containerId);
404 AddDialogSubwindow(containerId, subwindow);
405 }
406 return subwindow;
407 }
408
ShowToast(const std::string & message,int32_t duration,const std::string & bottom)409 void SubwindowManager::ShowToast(const std::string& message, int32_t duration, const std::string& bottom)
410 {
411 auto containerId = Container::CurrentId();
412 // Get active container when current instanceid is less than 0
413 if (containerId < 0) {
414 auto container = Container::GetActive();
415 if (container) {
416 containerId = container->GetInstanceId();
417 }
418 }
419 // for pa service
420 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
421 auto subwindow = GetOrCreateSubWindow();
422 CHECK_NULL_VOID(subwindow);
423 subwindow->ShowToast(message, duration, bottom);
424 // for ability
425 } else {
426 auto taskExecutor = Container::CurrentTaskExecutor();
427 CHECK_NULL_VOID(taskExecutor);
428 taskExecutor->PostTask(
429 [containerId, message, duration, bottom] {
430 auto manager = SubwindowManager::GetInstance();
431 CHECK_NULL_VOID(manager);
432 auto subwindow = manager->GetSubwindow(containerId);
433 if (!subwindow) {
434 LOGI("Subwindow is null, add a new one.");
435 subwindow = Subwindow::CreateSubwindow(containerId);
436 subwindow->InitContainer();
437 manager->AddSubwindow(containerId, subwindow);
438 }
439 subwindow->ShowToast(message, duration, bottom);
440 },
441 TaskExecutor::TaskType::PLATFORM);
442 }
443 }
444
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)445 void SubwindowManager::ShowDialog(const std::string& title, const std::string& message,
446 const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& napiCallback,
447 const std::set<std::string>& dialogCallbacks)
448 {
449 auto containerId = Container::CurrentId();
450 // Get active container when current instanceid is less than 0
451 if (containerId < 0) {
452 auto container = Container::GetActive();
453 if (container) {
454 containerId = container->GetInstanceId();
455 }
456 }
457 // for pa service
458 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
459 auto subwindow = GetOrCreateSubWindow();
460 CHECK_NULL_VOID(subwindow);
461 subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
462 // for ability
463 } else {
464 auto subwindow = GetSubwindow(containerId);
465 if (!subwindow) {
466 LOGI("Subwindow is null, add a new one.");
467 subwindow = Subwindow::CreateSubwindow(containerId);
468 subwindow->InitContainer();
469 AddSubwindow(containerId, subwindow);
470 }
471 subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
472 }
473 }
474
ShowDialog(const PromptDialogAttr & dialogAttr,const std::vector<ButtonInfo> & buttons,std::function<void (int32_t,int32_t)> && napiCallback,const std::set<std::string> & dialogCallbacks)475 void SubwindowManager::ShowDialog(const PromptDialogAttr& dialogAttr, const std::vector<ButtonInfo>& buttons,
476 std::function<void(int32_t, int32_t)>&& napiCallback, const std::set<std::string>& dialogCallbacks)
477 {
478 auto containerId = Container::CurrentId();
479 // Get active container when current instanceid is less than 0
480 if (containerId < 0) {
481 auto container = Container::GetActive();
482 if (container) {
483 containerId = container->GetInstanceId();
484 }
485 }
486 // for pa service
487 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
488 auto subWindow = GetOrCreateSubWindow();
489 CHECK_NULL_VOID(subWindow);
490 subWindow->ShowDialog(dialogAttr, buttons, std::move(napiCallback), dialogCallbacks);
491 // for ability
492 } else {
493 auto subWindow = GetSubwindow(containerId);
494 if (!subWindow) {
495 LOGI("SubWindow is null, add a new one.");
496 subWindow = Subwindow::CreateSubwindow(containerId);
497 subWindow->InitContainer();
498 AddSubwindow(containerId, subWindow);
499 }
500 subWindow->ShowDialog(dialogAttr, buttons, std::move(napiCallback), dialogCallbacks);
501 }
502 }
503
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)504 void SubwindowManager::ShowActionMenu(
505 const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
506 {
507 auto containerId = Container::CurrentId();
508 // Get active container when current instanceid is less than 0
509 if (containerId < 0) {
510 auto container = Container::GetActive();
511 if (container) {
512 containerId = container->GetInstanceId();
513 }
514 }
515 // for pa service
516 if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
517 auto subwindow = GetOrCreateSubWindow();
518 CHECK_NULL_VOID(subwindow);
519 subwindow->ShowActionMenu(title, button, std::move(callback));
520 // for ability
521 } else {
522 auto subwindow = GetSubwindow(containerId);
523 if (!subwindow) {
524 LOGI("Subwindow is null, add a new one.");
525 subwindow = Subwindow::CreateSubwindow(containerId);
526 subwindow->InitContainer();
527 AddSubwindow(containerId, subwindow);
528 }
529 subwindow->ShowActionMenu(title, button, std::move(callback));
530 }
531 }
532
CloseDialog(int32_t instanceId)533 void SubwindowManager::CloseDialog(int32_t instanceId)
534 {
535 LOGI("SubwindowManager::CloseDialog containerId = %{public}d.", instanceId);
536 auto subwindow = GetDialogSubwindow(instanceId);
537 if (!subwindow) {
538 LOGE("SubwindowManager::CloseDialog Subwindow is null.");
539 return;
540 }
541 for (auto& containerMap : parentContainerMap_) {
542 if (containerMap.second == instanceId) {
543 subwindow->CloseDialog(containerMap.first);
544 }
545 }
546 }
547
HideSubWindowNG()548 void SubwindowManager::HideSubWindowNG()
549 {
550 RefPtr<Subwindow> subwindow;
551 auto container = Container::Current();
552 CHECK_NULL_VOID(container);
553 if (container->IsDialogContainer()) {
554 subwindow = GetCurrentDialogWindow();
555 } else {
556 subwindow = GetCurrentWindow();
557 }
558 if (subwindow) {
559 subwindow->HideSubWindowNG();
560 }
561 }
562
RegisterOnShowMenu(const std::function<void ()> & callback)563 void SubwindowManager::RegisterOnShowMenu(const std::function<void()>& callback)
564 {
565 onShowMenuCallback_ = callback;
566 if (currentSubwindow_) {
567 auto overlayManager = currentSubwindow_->GetOverlayManager();
568 CHECK_NULL_VOID(overlayManager);
569 overlayManager->RegisterOnShowMenu(callback);
570 }
571 }
572
RegisterOnHideMenu(const std::function<void ()> & callback)573 void SubwindowManager::RegisterOnHideMenu(const std::function<void()>& callback)
574 {
575 onHideMenuCallback_ = callback;
576 if (currentSubwindow_) {
577 auto overlayManager = currentSubwindow_->GetOverlayManager();
578 CHECK_NULL_VOID(overlayManager);
579 overlayManager->RegisterOnHideMenu(callback);
580 }
581 }
582
RequestFocusSubwindow(int32_t instanceId)583 void SubwindowManager::RequestFocusSubwindow(int32_t instanceId)
584 {
585 RefPtr<Subwindow> subwindow;
586 if (instanceId != -1) {
587 // get the subwindow which overlay node in, not current
588 subwindow = GetSubwindow(instanceId >= MIN_SUBCONTAINER_ID ? GetParentContainerId(instanceId) : instanceId);
589 } else {
590 subwindow = GetCurrentWindow();
591 }
592 if (subwindow) {
593 subwindow->RequestFocus();
594 }
595 }
596 } // namespace OHOS::Ace
597