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