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 "window_inner_manager.h"
17
18 #include "ability_manager_client.h"
19 #include "memory_guard.h"
20 #include "window.h"
21 #include "window_manager_hilog.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowInnerManager"};
27 }
WM_IMPLEMENT_SINGLE_INSTANCE(WindowInnerManager)28 WM_IMPLEMENT_SINGLE_INSTANCE(WindowInnerManager)
29
30 WindowInnerManager::WindowInnerManager() : eventHandler_(nullptr), eventLoop_(nullptr),
31 state_(InnerWMRunningState::STATE_NOT_START)
32 {
33 }
34
~WindowInnerManager()35 WindowInnerManager::~WindowInnerManager()
36 {
37 Stop();
38 }
39
Init()40 bool WindowInnerManager::Init()
41 {
42 // create handler for inner command at server
43 eventLoop_ = AppExecFwk::EventRunner::Create(INNER_WM_THREAD_NAME);
44 if (eventLoop_ == nullptr) {
45 return false;
46 }
47 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
48 if (eventHandler_ == nullptr) {
49 return false;
50 }
51
52 eventHandler_->PostTask([]() { MemoryGuard cacheGuard; }, AppExecFwk::EventQueue::Priority::IMMEDIATE);
53 moveDragController_ = new MoveDragController();
54 if (!moveDragController_->Init()) {
55 WLOGFE("Init window drag controller failed");
56 return false;
57 }
58
59 WLOGFI("init window inner manager service success.");
60 return true;
61 }
62
Start(bool enableRecentholder)63 void WindowInnerManager::Start(bool enableRecentholder)
64 {
65 isRecentHolderEnable_ = enableRecentholder;
66 if (state_ == InnerWMRunningState::STATE_RUNNING) {
67 WLOGFI("window inner manager service has already started.");
68 }
69 if (!Init()) {
70 WLOGFI("failed to init window inner manager service.");
71 return;
72 }
73 state_ = InnerWMRunningState::STATE_RUNNING;
74 eventLoop_->Run();
75
76 pid_ = getpid();
77 WLOGFI("window inner manager service start success.");
78 }
79
Stop()80 void WindowInnerManager::Stop()
81 {
82 WLOGFI("stop window inner manager service.");
83 if (eventLoop_ != nullptr) {
84 eventLoop_->Stop();
85 eventLoop_.reset();
86 }
87 if (eventHandler_ != nullptr) {
88 eventHandler_.reset();
89 }
90 if (moveDragController_ != nullptr) {
91 moveDragController_->Stop();
92 }
93 state_ = InnerWMRunningState::STATE_NOT_START;
94 }
95
CreateInnerWindow(std::string name,DisplayId displayId,Rect rect,WindowType type,WindowMode mode)96 void WindowInnerManager::CreateInnerWindow(std::string name, DisplayId displayId, Rect rect,
97 WindowType type, WindowMode mode)
98 {
99 bool recentHolderWindowFlag = isRecentHolderEnable_;
100 auto task = [name, displayId, rect, mode, type, recentHolderWindowFlag]() {
101 switch (type) {
102 case WindowType::WINDOW_TYPE_PLACEHOLDER: {
103 if (recentHolderWindowFlag) {
104 PlaceHolderWindow::GetInstance().Create(name, displayId, rect, mode);
105 }
106 break;
107 }
108 default:
109 break;
110 }
111 };
112 PostTask(task, "CreateInnerWindow");
113 return;
114 }
115
DestroyInnerWindow(DisplayId displayId,WindowType type)116 void WindowInnerManager::DestroyInnerWindow(DisplayId displayId, WindowType type)
117 {
118 bool recentHolderWindowFlag = isRecentHolderEnable_;
119 auto task = [type, recentHolderWindowFlag]() {
120 switch (type) {
121 case WindowType::WINDOW_TYPE_PLACEHOLDER: {
122 if (recentHolderWindowFlag) {
123 PlaceHolderWindow::GetInstance().Destroy();
124 }
125 break;
126 }
127 default:
128 break;
129 }
130 };
131 PostTask(task, "DestroyInnerWindow");
132 return;
133 }
134
UpdateInnerWindow(DisplayId displayId,WindowType type,uint32_t width,uint32_t height)135 void WindowInnerManager::UpdateInnerWindow(DisplayId displayId, WindowType type, uint32_t width, uint32_t height)
136 {
137 bool recentHolderWindowFlag = isRecentHolderEnable_;
138 auto task = [type, width, height, recentHolderWindowFlag]() {
139 switch (type) {
140 case WindowType::WINDOW_TYPE_PLACEHOLDER: {
141 if (recentHolderWindowFlag) {
142 PlaceHolderWindow::GetInstance().Update(width, height);
143 }
144 break;
145 }
146 default:
147 break;
148 }
149 };
150 PostTask(task, "UpdateInnerWindow");
151 return;
152 }
153
MinimizeAbility(const wptr<WindowNode> & node,bool isFromUser)154 void WindowInnerManager::MinimizeAbility(const wptr<WindowNode> &node, bool isFromUser)
155 {
156 // asynchronously calls the MinimizeAbility of AbilityManager
157 auto weakNode = node.promote();
158 if (weakNode == nullptr) {
159 WLOGFE("minimize ability failed.");
160 return;
161 }
162 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
163 WLOGFD("minimize window %{public}u, isfromuser: %{public}d", weakNode->GetWindowId(), isFromUser);
164 auto task = [weakToken, isFromUser]() {
165 auto token = weakToken.promote();
166 if (token == nullptr) {
167 WLOGE("minimize ability failed, because window token is nullptr.");
168 return;
169 }
170 AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(token, isFromUser);
171 };
172 PostTask(task, "MinimizeAbility");
173 }
174
TerminateAbility(const wptr<WindowNode> & node)175 void WindowInnerManager::TerminateAbility(const wptr<WindowNode> &node)
176 {
177 // asynchronously calls the TerminateAbility of AbilityManager
178 auto weakNode = node.promote();
179 if (weakNode == nullptr) {
180 WLOGFE("terminate ability failed.");
181 return;
182 }
183 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
184 WLOGFD("terminate window %{public}u", weakNode->GetWindowId());
185 auto task = [weakToken]() {
186 auto token = weakToken.promote();
187 if (token == nullptr) {
188 WLOGE("terminate ability failed, because window token is nullptr.");
189 return;
190 }
191 AAFwk::Want resultWant;
192 AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token, -1, &resultWant);
193 };
194 PostTask(task, "TerminateAbility");
195 }
196
CloseAbility(const wptr<WindowNode> & node)197 void WindowInnerManager::CloseAbility(const wptr<WindowNode> &node)
198 {
199 // asynchronously calls the CloseAbility of AbilityManager
200 auto weakNode = node.promote();
201 if (weakNode == nullptr) {
202 WLOGFE("close ability failed.");
203 return;
204 }
205 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
206 WLOGFD("close window %{public}u", weakNode->GetWindowId());
207 auto task = [weakToken]() {
208 auto token = weakToken.promote();
209 if (token == nullptr) {
210 WLOGE("close ability failed, because window token is nullptr.");
211 return;
212 }
213 AAFwk::Want resultWant;
214 AAFwk::AbilityManagerClient::GetInstance()->CloseAbility(token);
215 };
216 PostTask(task, "CloseAbility");
217 }
218
CompleteFirstFrameDrawing(const wptr<WindowNode> & node)219 void WindowInnerManager::CompleteFirstFrameDrawing(const wptr<WindowNode> &node)
220 {
221 // asynchronously calls the CloseAbility of AbilityManager
222 auto weakNode = node.promote();
223 if (weakNode == nullptr) {
224 WLOGFE("CompleteFirstFrameDrawing failed.");
225 return;
226 }
227 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
228 WLOGFD("CompleteFirstFrameDrawing %{public}u", weakNode->GetWindowId());
229 auto task = [weakToken]() {
230 auto token = weakToken.promote();
231 if (token == nullptr) {
232 WLOGE("CompleteFirstFrameDrawing failed, because window token is nullptr.");
233 return;
234 }
235 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(token);
236 };
237 PostTask(task, "CompleteFirstFrameDrawing");
238 }
239
PostTask(InnerTask && task,std::string name,EventPriority priority)240 void WindowInnerManager::PostTask(InnerTask &&task, std::string name, EventPriority priority)
241 {
242 if (eventHandler_ == nullptr) {
243 WLOGFE("listener handler is nullptr");
244 return;
245 }
246 bool ret = eventHandler_->PostTask(task, name, 0, priority); // 0 is task delay time
247 if (!ret) {
248 WLOGFE("post listener callback task failed.");
249 return;
250 }
251 return;
252 }
253
GetPid()254 pid_t WindowInnerManager::GetPid()
255 {
256 return pid_;
257 }
258
SetInputEventConsumer()259 void WindowInnerManager::SetInputEventConsumer()
260 {
261 if (moveDragController_ == nullptr) {
262 return;
263 }
264 moveDragController_->SetInputEventConsumer();
265 }
266
NotifyDisplayChange(const std::map<DisplayId,Rect> & displayRectMap)267 void WindowInnerManager::NotifyDisplayChange(const std::map<DisplayId, Rect>& displayRectMap)
268 {
269 if (moveDragController_ == nullptr) {
270 return;
271 }
272 moveDragController_->HandleDisplayChange(displayRectMap);
273 }
274
NotifyServerReadyToMoveOrDrag(uint32_t windowId,sptr<WindowProperty> & windowProperty,sptr<MoveDragProperty> & moveDragProperty)275 bool WindowInnerManager::NotifyServerReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty,
276 sptr<MoveDragProperty>& moveDragProperty)
277 {
278 if (moveDragController_->GetActiveWindowId() != INVALID_WINDOW_ID) {
279 WLOGFW("Is already in dragging or moving state, invalid operation");
280 return false;
281 }
282 moveDragController_->HandleReadyToMoveOrDrag(windowId, windowProperty, moveDragProperty);
283 WLOGFI("NotifyServerReadyToMoveOrDrag, windowId: %{public}u", windowId);
284 return true;
285 }
286
NotifyWindowEndUpMovingOrDragging(uint32_t windowId)287 void WindowInnerManager::NotifyWindowEndUpMovingOrDragging(uint32_t windowId)
288 {
289 if (moveDragController_->GetActiveWindowId() != windowId) {
290 return;
291 }
292 moveDragController_->HandleEndUpMovingOrDragging(windowId);
293 WLOGFI("NotifyWindowEndUpMovingOrDragging, windowId: %{public}u", windowId);
294 }
295
NotifyWindowRemovedOrDestroyed(uint32_t windowId)296 void WindowInnerManager::NotifyWindowRemovedOrDestroyed(uint32_t windowId)
297 {
298 if (moveDragController_->GetActiveWindowId() != windowId) {
299 return;
300 }
301 moveDragController_->HandleWindowRemovedOrDestroyed(windowId);
302 WLOGFI("NotifyWindowRemovedOrDestroyed, windowId: %{public}u", windowId);
303 }
304
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)305 void WindowInnerManager::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
306 {
307 uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
308 if (moveDragController_->GetActiveWindowId() != windowId ||
309 moveDragController_->GetActiveWindowId() == INVALID_WINDOW_ID) {
310 WLOGFE("active winId or inputEvent winId is invalid, windowId: %{public}u, activeWinId: %{public}u",
311 windowId, moveDragController_->GetActiveWindowId());
312 return;
313 }
314 moveDragController_->ConsumePointerEvent(pointerEvent);
315 }
316 } // Rosen
317 } // OHOS
318