• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/log/log.h"
24 #include "base/memory/ace_type.h"
25 #include "core/common/ace_page.h"
26 #include "core/common/container.h"
27 
28 namespace OHOS::Ace {
29 
30 std::mutex SubwindowManager::instanceMutex_;
31 std::shared_ptr<SubwindowManager> SubwindowManager::instance_;
32 
GetInstance()33 std::shared_ptr<SubwindowManager> SubwindowManager::GetInstance()
34 {
35     std::lock_guard<std::mutex> lock(instanceMutex_);
36     if (!instance_) {
37         instance_ = std::make_shared<SubwindowManager>();
38     }
39     return instance_;
40 }
41 
AddContainerId(uint32_t windowId,int32_t containerId)42 void SubwindowManager::AddContainerId(uint32_t windowId, int32_t containerId)
43 {
44     std::lock_guard<std::mutex> lock(mutex_);
45     auto result = containerMap_.try_emplace(windowId, containerId);
46     if (!result.second) {
47         LOGW("Already have container of this windowId, windowId: %{public}u", windowId);
48     }
49 }
50 
RemoveContainerId(uint32_t windowId)51 void SubwindowManager::RemoveContainerId(uint32_t windowId)
52 {
53     std::lock_guard<std::mutex> lock(mutex_);
54     containerMap_.erase(windowId);
55 }
56 
GetContainerId(uint32_t windowId)57 int32_t SubwindowManager::GetContainerId(uint32_t windowId)
58 {
59     std::lock_guard<std::mutex> lock(mutex_);
60     auto result = containerMap_.find(windowId);
61     if (result != containerMap_.end()) {
62         return result->second;
63     } else {
64         return -1;
65     }
66 }
67 
AddParentContainerId(int32_t containerId,int32_t parentContainerId)68 void SubwindowManager::AddParentContainerId(int32_t containerId, int32_t parentContainerId)
69 {
70     LOGI("Container id is %{public}d, parent id is %{public}d.", containerId, parentContainerId);
71     std::lock_guard<std::mutex> lock(parentMutex_);
72     auto result = parentContainerMap_.try_emplace(containerId, parentContainerId);
73     if (!result.second) {
74         LOGW("Already have container of this %{public}d", containerId);
75     }
76 }
77 
RemoveParentContainerId(int32_t containerId)78 void SubwindowManager::RemoveParentContainerId(int32_t containerId)
79 {
80     std::lock_guard<std::mutex> lock(parentMutex_);
81     parentContainerMap_.erase(containerId);
82 }
83 
GetParentContainerId(int32_t containerId)84 int32_t SubwindowManager::GetParentContainerId(int32_t containerId)
85 {
86     std::lock_guard<std::mutex> lock(parentMutex_);
87     auto result = parentContainerMap_.find(containerId);
88     if (result != parentContainerMap_.end()) {
89         return result->second;
90     } else {
91         return 0;
92     }
93 }
94 
AddSubwindow(int32_t instanceId,RefPtr<Subwindow> subwindow)95 void SubwindowManager::AddSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
96 {
97     if (!subwindow) {
98         LOGE("Add subwindow failed, the subwindow is null.");
99         return;
100     }
101     LOGI("Add subwindow into map, instanceId is %{public}d, subwindow id is %{public}d.", instanceId,
102         subwindow->GetSubwindowId());
103     std::lock_guard<std::mutex> lock(subwindowMutex_);
104     auto result = subwindowMap_.try_emplace(instanceId, subwindow);
105     if (!result.second) {
106         LOGE("Add failed of this instance %{public}d", instanceId);
107         return;
108     }
109     LOGI("Add subwindow success of this instance %{public}d.", instanceId);
110 }
111 
RemoveSubwindow(int32_t instanceId)112 void SubwindowManager::RemoveSubwindow(int32_t instanceId)
113 {
114     LOGI("Remove subwindow of this instance %{public}d", instanceId);
115     std::lock_guard<std::mutex> lock(subwindowMutex_);
116     int res = static_cast<int>(subwindowMap_.erase(instanceId));
117     if (res == 0) {
118         LOGW("Remove subwindow of instance %{public}d failed.", instanceId);
119     }
120 }
121 
GetSubwindow(int32_t instanceId)122 const RefPtr<Subwindow> SubwindowManager::GetSubwindow(int32_t instanceId)
123 {
124     LOGI("Get subwindow of instance %{public}d.", instanceId);
125     std::lock_guard<std::mutex> lock(subwindowMutex_);
126     auto result = subwindowMap_.find(instanceId);
127     if (result != subwindowMap_.end()) {
128         return result->second;
129     } else {
130         return nullptr;
131     }
132 }
133 
SetCurrentSubwindowName(const std::string & currentSubwindowName)134 void SubwindowManager::SetCurrentSubwindowName(const std::string& currentSubwindowName)
135 {
136     std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
137     currentSubwindowName_ = currentSubwindowName;
138 }
139 
GetCurrentSubWindowName()140 std::string SubwindowManager::GetCurrentSubWindowName()
141 {
142     std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
143     return currentSubwindowName_;
144 }
145 
SetCurrentSubwindow(const RefPtr<Subwindow> & subwindow)146 void SubwindowManager::SetCurrentSubwindow(const RefPtr<Subwindow>& subwindow)
147 {
148     std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
149     currentSubwindow_ = subwindow;
150 }
151 
GetCurrentWindow()152 const RefPtr<Subwindow>& SubwindowManager::GetCurrentWindow()
153 {
154     std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
155     return currentSubwindow_;
156 }
157 
ShowMenuNG(const RefPtr<NG::FrameNode> menuNode,int32_t targetId,const NG::OffsetF & offset)158 void SubwindowManager::ShowMenuNG(const RefPtr<NG::FrameNode> menuNode, int32_t targetId,
159     const NG::OffsetF& offset)
160 {
161     auto containerId = Container::CurrentId();
162     auto subwindow = GetSubwindow(containerId);
163     if (!subwindow) {
164         LOGI("Subwindow is null, add a new one.");
165         subwindow = Subwindow::CreateSubwindow(containerId);
166         subwindow->InitContainer();
167         AddSubwindow(containerId, subwindow);
168     }
169     subwindow->ShowMenuNG(menuNode, targetId, offset);
170 }
171 
HideMenuNG(int32_t targetId)172 void SubwindowManager::HideMenuNG(int32_t targetId)
173 {
174     auto subwindow = GetCurrentWindow();
175     if (subwindow) {
176         subwindow->HideMenuNG(targetId);
177     }
178 }
179 
HideMenuNG()180 void SubwindowManager::HideMenuNG()
181 {
182     auto subwindow = GetCurrentWindow();
183     if (subwindow) {
184         subwindow->HideMenuNG();
185     }
186 }
187 
ClearMenuNG()188 void SubwindowManager::ClearMenuNG()
189 {
190     auto subwindow = GetCurrentWindow();
191     if (subwindow) {
192         subwindow->ClearMenuNG();
193     }
194 }
195 
ShowPopupNG(int32_t targetId,const NG::PopupInfo & popupInfo)196 void SubwindowManager::ShowPopupNG(int32_t targetId, const NG::PopupInfo& popupInfo)
197 {
198     auto containerId = Container::CurrentId();
199     auto subwindow = GetSubwindow(containerId);
200     if (!subwindow) {
201         LOGI("Subwindow is null, add a new one.");
202         subwindow = Subwindow::CreateSubwindow(containerId);
203         subwindow->InitContainer();
204         AddSubwindow(containerId, subwindow);
205     }
206     subwindow->ShowPopupNG(targetId, popupInfo);
207 }
208 
HidePopupNG(int32_t targetId)209 void SubwindowManager::HidePopupNG(int32_t targetId)
210 {
211     auto subwindow = GetCurrentWindow();
212     if (subwindow) {
213         subwindow->HidePopupNG(targetId);
214     }
215 }
216 
HidePopupNG()217 void SubwindowManager::HidePopupNG()
218 {
219     auto subwindow = GetCurrentWindow();
220     if (subwindow) {
221         subwindow->HidePopupNG();
222     }
223 }
224 
ShowPopup(const RefPtr<Component> & newComponent,bool disableTouchEvent)225 void SubwindowManager::ShowPopup(const RefPtr<Component>& newComponent, bool disableTouchEvent)
226 {
227     auto containerId = Container::CurrentId();
228     auto subwindow = GetSubwindow(containerId);
229     if (!subwindow) {
230         LOGI("Subwindow is null, add a new one.");
231         subwindow = Subwindow::CreateSubwindow(containerId);
232         subwindow->InitContainer();
233         AddSubwindow(containerId, subwindow);
234     }
235     subwindow->ShowPopup(newComponent, disableTouchEvent);
236 }
237 
CancelPopup(const std::string & id)238 bool SubwindowManager::CancelPopup(const std::string& id)
239 {
240     auto subwindow = GetCurrentWindow();
241     if (subwindow) {
242         return subwindow->CancelPopup(id);
243     }
244     return false;
245 }
246 
ShowMenu(const RefPtr<Component> & newComponent)247 void SubwindowManager::ShowMenu(const RefPtr<Component>& newComponent)
248 {
249     auto containerId = Container::CurrentId();
250     auto subwindow = GetSubwindow(containerId);
251     if (!subwindow) {
252         LOGI("Subwindow is null, add a new one.");
253         subwindow = Subwindow::CreateSubwindow(containerId);
254         subwindow->InitContainer();
255         AddSubwindow(containerId, subwindow);
256     }
257     subwindow->ShowMenu(newComponent);
258 }
259 
CloseMenu()260 void SubwindowManager::CloseMenu()
261 {
262     auto subwindow = GetCurrentWindow();
263     if (subwindow) {
264         subwindow->CloseMenu();
265     }
266 }
267 
ClearMenu()268 void SubwindowManager::ClearMenu()
269 {
270     auto subwindow = GetCurrentWindow();
271     if (subwindow) {
272         subwindow->ClearMenu();
273     }
274 }
275 
SetHotAreas(const std::vector<Rect> & rects)276 void SubwindowManager::SetHotAreas(const std::vector<Rect>& rects)
277 {
278     auto subwindow = GetCurrentWindow();
279     if (subwindow) {
280         subwindow->SetHotAreas(rects);
281     }
282 }
283 
ShowDialogNG(const DialogProperties & dialogProps,const RefPtr<NG::UINode> & customNode)284 RefPtr<NG::FrameNode> SubwindowManager::ShowDialogNG(
285     const DialogProperties& dialogProps, const RefPtr<NG::UINode>& customNode)
286 {
287     auto containerId = Container::CurrentId();
288     auto subwindow = GetSubwindow(containerId);
289     if (!subwindow) {
290         LOGI("Subwindow is null, add a new one.");
291         subwindow = Subwindow::CreateSubwindow(containerId);
292         subwindow->InitContainer();
293         AddSubwindow(containerId, subwindow);
294     }
295     return subwindow->ShowDialogNG(dialogProps, customNode);
296 }
297 
AddDialogSubwindow(int32_t instanceId,const RefPtr<Subwindow> & subwindow)298 void SubwindowManager::AddDialogSubwindow(int32_t instanceId, const RefPtr<Subwindow>& subwindow)
299 {
300     if (!subwindow) {
301         LOGE("Add dialog subwindow failed, the subwindow is null.");
302         return;
303     }
304     LOGI("Add dialog subwindow into map, instanceId is %{public}d, subwindow id is %{public}d.", instanceId,
305         subwindow->GetSubwindowId());
306     std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
307     auto result = dialogSubwindowMap_.try_emplace(instanceId, subwindow);
308     if (!result.second) {
309         LOGE("Add dialog failed of this instance %{public}d", instanceId);
310         return;
311     }
312     LOGI("Add dialog subwindow success of this instance %{public}d.", instanceId);
313 }
314 
GetDialogSubwindow(int32_t instanceId)315 const RefPtr<Subwindow> SubwindowManager::GetDialogSubwindow(int32_t instanceId)
316 {
317     LOGI("Get dialog subwindow of instance %{public}d.", instanceId);
318     std::lock_guard<std::mutex> lock(dialogSubwindowMutex_);
319     auto result = dialogSubwindowMap_.find(instanceId);
320     if (result != dialogSubwindowMap_.end()) {
321         return result->second;
322     } else {
323         return nullptr;
324     }
325 }
326 
SetCurrentDialogSubwindow(const RefPtr<Subwindow> & subwindow)327 void SubwindowManager::SetCurrentDialogSubwindow(const RefPtr<Subwindow>& subwindow)
328 {
329     std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
330     currentDialogSubwindow_ = subwindow;
331 }
332 
GetCurrentDialogWindow()333 const RefPtr<Subwindow>& SubwindowManager::GetCurrentDialogWindow()
334 {
335     std::lock_guard<std::mutex> lock(currentDialogSubwindowMutex_);
336     return currentDialogSubwindow_;
337 }
338 
GetOrCreateSubWindow()339 RefPtr<Subwindow> SubwindowManager::GetOrCreateSubWindow()
340 {
341     auto containerId = Container::CurrentId();
342     LOGI("SubwindowManager::GetOrCreateSubWindow containerId = %{public}d.", containerId);
343     auto subwindow = GetDialogSubwindow(containerId);
344     if (!subwindow) {
345         LOGI("Subwindow is null, add a new one.");
346         subwindow = Subwindow::CreateSubwindow(containerId);
347         AddDialogSubwindow(containerId, subwindow);
348     }
349     return subwindow;
350 }
351 
ShowToast(const std::string & message,int32_t duration,const std::string & bottom)352 void SubwindowManager::ShowToast(const std::string& message, int32_t duration, const std::string& bottom)
353 {
354     auto containerId = Container::CurrentId();
355     // Get active container when current instanceid is less than 0
356     if (containerId < 0) {
357         auto container = Container::GetActive();
358         if (container) {
359             containerId = container->GetInstanceId();
360         }
361     }
362     // for pa service
363     if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
364         auto subwindow = GetOrCreateSubWindow();
365         CHECK_NULL_VOID(subwindow);
366         subwindow->ShowToast(message, duration, bottom);
367         // for ability
368     } else {
369         auto subwindow = GetSubwindow(containerId);
370         if (!subwindow) {
371             LOGI("Subwindow is null, add a new one.");
372             subwindow = Subwindow::CreateSubwindow(containerId);
373             subwindow->InitContainer();
374             AddSubwindow(containerId, subwindow);
375         }
376         subwindow->ShowToast(message, duration, bottom);
377     }
378 }
379 
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)380 void SubwindowManager::ShowDialog(const std::string& title, const std::string& message,
381     const std::vector<ButtonInfo>& buttons, bool autoCancel, std::function<void(int32_t, int32_t)>&& napiCallback,
382     const std::set<std::string>& dialogCallbacks)
383 {
384     auto containerId = Container::CurrentId();
385     // Get active container when current instanceid is less than 0
386     if (containerId < 0) {
387         auto container = Container::GetActive();
388         if (container) {
389             containerId = container->GetInstanceId();
390         }
391     }
392     // for pa service
393     if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
394         auto subwindow = GetOrCreateSubWindow();
395         CHECK_NULL_VOID(subwindow);
396         subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
397         // for ability
398     } else {
399         auto subwindow = GetSubwindow(containerId);
400         if (!subwindow) {
401             LOGI("Subwindow is null, add a new one.");
402             subwindow = Subwindow::CreateSubwindow(containerId);
403             subwindow->InitContainer();
404             AddSubwindow(containerId, subwindow);
405         }
406         subwindow->ShowDialog(title, message, buttons, autoCancel, std::move(napiCallback), dialogCallbacks);
407     }
408 }
409 
ShowActionMenu(const std::string & title,const std::vector<ButtonInfo> & button,std::function<void (int32_t,int32_t)> && callback)410 void SubwindowManager::ShowActionMenu(
411     const std::string& title, const std::vector<ButtonInfo>& button, std::function<void(int32_t, int32_t)>&& callback)
412 {
413     auto containerId = Container::CurrentId();
414     // Get active container when current instanceid is less than 0
415     if (containerId < 0) {
416         auto container = Container::GetActive();
417         if (container) {
418             containerId = container->GetInstanceId();
419         }
420     }
421     // for pa service
422     if (containerId >= MIN_PA_SERVICE_ID || containerId < 0) {
423         auto subwindow = GetOrCreateSubWindow();
424         CHECK_NULL_VOID(subwindow);
425         subwindow->ShowActionMenu(title, button, std::move(callback));
426         // for ability
427     } else {
428         auto subwindow = GetSubwindow(containerId);
429         if (!subwindow) {
430             LOGI("Subwindow is null, add a new one.");
431             subwindow = Subwindow::CreateSubwindow(containerId);
432             subwindow->InitContainer();
433             AddSubwindow(containerId, subwindow);
434         }
435         subwindow->ShowActionMenu(title, button, std::move(callback));
436     }
437 }
438 
CloseDialog(int32_t instanceId)439 void SubwindowManager::CloseDialog(int32_t instanceId)
440 {
441     LOGI("SubwindowManager::CloseDialog containerId = %{public}d.", instanceId);
442     auto subwindow = GetDialogSubwindow(instanceId);
443     if (!subwindow) {
444         LOGE("SubwindowManager::CloseDialog Subwindow is null.");
445         return;
446     }
447     for (auto& containerMap : parentContainerMap_) {
448         if (containerMap.second == instanceId) {
449             subwindow->CloseDialog(containerMap.first);
450         }
451     }
452 }
453 
HideSubWindowNG()454 void SubwindowManager::HideSubWindowNG()
455 {
456     RefPtr<Subwindow> subwindow;
457     auto container = Container::Current();
458     CHECK_NULL_VOID(container);
459     if (container->IsDialogContainer()) {
460         subwindow = GetCurrentDialogWindow();
461     } else {
462         subwindow = GetCurrentWindow();
463     }
464     if (subwindow) {
465         subwindow->HideSubWindowNG();
466     }
467 }
468 } // namespace OHOS::Ace
469