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