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/container.h"
26
27 namespace OHOS::Ace {
28
29 std::mutex SubwindowManager::instanceMutex_;
30 std::shared_ptr<SubwindowManager> SubwindowManager::instance_;
31
GetInstance()32 std::shared_ptr<SubwindowManager> SubwindowManager::GetInstance()
33 {
34 std::lock_guard<std::mutex> lock(instanceMutex_);
35 if (!instance_) {
36 instance_ = std::make_shared<SubwindowManager>();
37 }
38 return instance_;
39 }
40
AddContainerId(uint32_t windowId,int32_t containerId)41 void SubwindowManager::AddContainerId(uint32_t windowId, int32_t containerId)
42 {
43 std::lock_guard<std::mutex> lock(mutex_);
44 auto result = containerMap_.try_emplace(windowId, containerId);
45 if (!result.second) {
46 LOGW("Already have container of this windowId, windowId: %{public}u", windowId);
47 }
48 }
49
RemoveContainerId(uint32_t windowId)50 void SubwindowManager::RemoveContainerId(uint32_t windowId)
51 {
52 std::lock_guard<std::mutex> lock(mutex_);
53 containerMap_.erase(windowId);
54 }
55
GetContainerId(uint32_t windowId)56 int32_t SubwindowManager::GetContainerId(uint32_t windowId)
57 {
58 std::lock_guard<std::mutex> lock(mutex_);
59 auto result = containerMap_.find(windowId);
60 if (result != containerMap_.end()) {
61 return result->second;
62 } else {
63 return -1;
64 }
65 }
66
AddParentContainerId(int32_t containerId,int32_t parentContainerId)67 void SubwindowManager::AddParentContainerId(int32_t containerId, int32_t parentContainerId)
68 {
69 LOGI("Container id is %{public}d, parent id is %{public}d.", containerId, parentContainerId);
70 std::lock_guard<std::mutex> lock(parentMutex_);
71 auto result = parentContainerMap_.try_emplace(containerId, parentContainerId);
72 if (!result.second) {
73 LOGW("Already have container of this %{public}d", containerId);
74 }
75 }
76
RemoveParentContainerId(int32_t containerId)77 void SubwindowManager::RemoveParentContainerId(int32_t containerId)
78 {
79 std::lock_guard<std::mutex> lock(parentMutex_);
80 parentContainerMap_.erase(containerId);
81 }
82
GetParentContainerId(int32_t containerId)83 int32_t SubwindowManager::GetParentContainerId(int32_t containerId)
84 {
85 std::lock_guard<std::mutex> lock(parentMutex_);
86 auto result = parentContainerMap_.find(containerId);
87 if (result != parentContainerMap_.end()) {
88 return result->second;
89 } else {
90 return 0;
91 }
92 }
93
AddSubwindow(int32_t instanceId,RefPtr<Subwindow> subwindow)94 void SubwindowManager::AddSubwindow(int32_t instanceId, RefPtr<Subwindow> subwindow)
95 {
96 if (!subwindow) {
97 LOGE("Add subwindow failed, the subwndow is null.");
98 return;
99 }
100 LOGI("Add subwindow into map, instanceId is %{public}d, subwindow id is %{public}d.", instanceId,
101 subwindow->GetSubwindowId());
102 std::lock_guard<std::mutex> lock(subwindowMutex_);
103 auto result = subwindowMap_.try_emplace(instanceId, subwindow);
104 if (!result.second) {
105 LOGE("Add failed of this instance %{public}d", instanceId);
106 return;
107 }
108 LOGI("Add subwindow success of this instance %{public}d.", instanceId);
109 }
110
RemoveSubwindow(int32_t instanceId)111 void SubwindowManager::RemoveSubwindow(int32_t instanceId)
112 {
113 LOGI("Remove subwindow of this instance %{public}d", instanceId);
114 std::lock_guard<std::mutex> lock(subwindowMutex_);
115 int res = static_cast<int>(subwindowMap_.erase(instanceId));
116 if (res == 0) {
117 LOGW("Remove subwindow of instance %{public}d failed.", instanceId);
118 }
119 }
120
GetSubwindow(int32_t instanceId)121 const RefPtr<Subwindow> SubwindowManager::GetSubwindow(int32_t instanceId)
122 {
123 LOGI("Get subwindow of instance %{public}d.", instanceId);
124 std::lock_guard<std::mutex> lock(subwindowMutex_);
125 auto result = subwindowMap_.find(instanceId);
126 if (result != subwindowMap_.end()) {
127 return result->second;
128 } else {
129 return nullptr;
130 }
131 }
132
SetCurrentSubwindowName(const std::string & currentSubwindowName)133 void SubwindowManager::SetCurrentSubwindowName(const std::string& currentSubwindowName)
134 {
135 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
136 currentSubwindowName_ = currentSubwindowName;
137 }
138
GetCurrentSubWindowName()139 std::string SubwindowManager::GetCurrentSubWindowName()
140 {
141 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
142 return currentSubwindowName_;
143 }
144
SetCurrentSubwindow(const RefPtr<Subwindow> & subwindow)145 void SubwindowManager::SetCurrentSubwindow(const RefPtr<Subwindow>& subwindow)
146 {
147 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
148 currentSubwindow_ = subwindow;
149 }
150
GetCurrentWindow()151 const RefPtr<Subwindow>& SubwindowManager::GetCurrentWindow()
152 {
153 std::lock_guard<std::mutex> lock(currentSubwindowMutex_);
154 return currentSubwindow_;
155 }
156
ShowMenu(const RefPtr<Component> & newComponent)157 void SubwindowManager::ShowMenu(const RefPtr<Component>& newComponent)
158 {
159 auto containerId = Container::CurrentId();
160 auto subwindow = GetSubwindow(containerId);
161 if (!subwindow) {
162 LOGI("Subwindow is null, add a new one.");
163 subwindow = Subwindow::CreateSubwindow(containerId);
164 subwindow->InitContainer();
165 AddSubwindow(containerId, subwindow);
166 }
167 subwindow->ShowMenu(newComponent);
168 }
169
CloseMenu()170 void SubwindowManager::CloseMenu()
171 {
172 auto subwindow = GetCurrentWindow();
173 if (subwindow) {
174 subwindow->CloseMenu();
175 }
176 }
177
ClearMenu()178 void SubwindowManager::ClearMenu()
179 {
180 auto subwindow = GetCurrentWindow();
181 if (subwindow) {
182 subwindow->ClearMenu();
183 }
184 }
185
186 } // namespace OHOS::Ace
187