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 PostTask([name, displayId, rect, mode, type, recentHolderWindowFlag]() {
107 if (type == WindowType::WINDOW_TYPE_PLACEHOLDER && recentHolderWindowFlag) {
108 PlaceHolderWindow::GetInstance().Create(name, displayId, rect, mode);
109 }
110 }, "CreateInnerWindow");
111 return;
112 }
113
DestroyInnerWindow(DisplayId displayId,WindowType type)114 void WindowInnerManager::DestroyInnerWindow(DisplayId displayId, WindowType type)
115 {
116 bool recentHolderWindowFlag = isRecentHolderEnable_;
117 PostTask([type, recentHolderWindowFlag]() {
118 if (type == WindowType::WINDOW_TYPE_PLACEHOLDER && recentHolderWindowFlag) {
119 PlaceHolderWindow::GetInstance().Destroy();
120 }
121 }, "DestroyInnerWindow");
122 return;
123 }
124
UpdateInnerWindow(DisplayId displayId,WindowType type,uint32_t width,uint32_t height)125 void WindowInnerManager::UpdateInnerWindow(DisplayId displayId, WindowType type, uint32_t width, uint32_t height)
126 {
127 bool recentHolderWindowFlag = isRecentHolderEnable_;
128 PostTask([type, width, height, recentHolderWindowFlag]() {
129 if (type == WindowType::WINDOW_TYPE_PLACEHOLDER && recentHolderWindowFlag) {
130 PlaceHolderWindow::GetInstance().Update(width, height);
131 }
132 }, "UpdateInnerWindow");
133 return;
134 }
135
MinimizeAbility(const wptr<WindowNode> & node,bool isFromUser)136 void WindowInnerManager::MinimizeAbility(const wptr<WindowNode>& node, bool isFromUser)
137 {
138 // asynchronously calls the MinimizeAbility of AbilityManager
139 auto weakNode = node.promote();
140 if (weakNode == nullptr) {
141 WLOGFE("minimize ability failed.");
142 return;
143 }
144 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
145 WLOGFD("minimize window %{public}u, isfromuser: %{public}d", weakNode->GetWindowId(), isFromUser);
146 PostTask([weakToken, isFromUser]() {
147 auto token = weakToken.promote();
148 if (token == nullptr) {
149 WLOGE("minimize ability failed, because window token is nullptr.");
150 return;
151 }
152 AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(token, isFromUser);
153 }, "MinimizeAbility");
154 }
155
TerminateAbility(const wptr<WindowNode> & node)156 void WindowInnerManager::TerminateAbility(const wptr<WindowNode>& node)
157 {
158 // asynchronously calls the TerminateAbility of AbilityManager
159 auto weakNode = node.promote();
160 if (weakNode == nullptr) {
161 WLOGFE("terminate ability failed.");
162 return;
163 }
164 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
165 WLOGFD("terminate window %{public}u", weakNode->GetWindowId());
166 PostTask([weakToken]() {
167 auto token = weakToken.promote();
168 if (token == nullptr) {
169 WLOGE("terminate ability failed, because window token is nullptr.");
170 return;
171 }
172 AAFwk::Want resultWant;
173 AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token, -1, &resultWant);
174 }, "TerminateAbility");
175 }
176
CloseAbility(const wptr<WindowNode> & node)177 void WindowInnerManager::CloseAbility(const wptr<WindowNode>& node)
178 {
179 // asynchronously calls the CloseAbility of AbilityManager
180 auto weakNode = node.promote();
181 if (weakNode == nullptr) {
182 WLOGFE("close ability failed.");
183 return;
184 }
185 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
186 WLOGFD("close window %{public}u", weakNode->GetWindowId());
187 PostTask([weakToken]() {
188 auto token = weakToken.promote();
189 if (token == nullptr) {
190 WLOGE("close ability failed, because window token is nullptr.");
191 return;
192 }
193 AAFwk::Want resultWant;
194 AAFwk::AbilityManagerClient::GetInstance()->CloseAbility(token);
195 }, "CloseAbility");
196 }
197
CompleteFirstFrameDrawing(const wptr<WindowNode> & node)198 void WindowInnerManager::CompleteFirstFrameDrawing(const wptr<WindowNode>& node)
199 {
200 // asynchronously calls the CloseAbility of AbilityManager
201 auto weakNode = node.promote();
202 if (weakNode == nullptr) {
203 WLOGFE("CompleteFirstFrameDrawing failed.");
204 return;
205 }
206 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
207 WLOGFD("CompleteFirstFrameDrawing %{public}u", weakNode->GetWindowId());
208 PostTask([weakToken]() {
209 auto token = weakToken.promote();
210 if (token == nullptr) {
211 WLOGE("CompleteFirstFrameDrawing failed, because window token is nullptr.");
212 return;
213 }
214 AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(token);
215 }, "CompleteFirstFrameDrawing");
216 }
217
UpdateMissionSnapShot(const wptr<WindowNode> & node,std::shared_ptr<Media::PixelMap> pixelMap)218 void WindowInnerManager::UpdateMissionSnapShot(const wptr<WindowNode>& node, std::shared_ptr<Media::PixelMap> pixelMap)
219 {
220 // asynchronously calls the UpdateMissionSnapShot of AbilityManager
221 auto weakNode = node.promote();
222 if (weakNode == nullptr) {
223 WLOGFE("UpdateMissionSnapShot failed.");
224 return;
225 }
226 wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
227 WLOGFD("Update id %{public}u", weakNode->GetWindowId());
228 PostTask([weakToken, pixelMap]() {
229 auto token = weakToken.promote();
230 if (token == nullptr) {
231 WLOGE("UpdateMissionSnapShot failed, because window token is nullptr.");
232 return;
233 }
234 if (pixelMap == nullptr) {
235 WLOGE("UpdateMissionSnapShot failed, because pixelMap is nullptr.");
236 return;
237 }
238 AAFwk::AbilityManagerClient::GetInstance()->UpdateMissionSnapShot(token, pixelMap);
239 }, "UpdateMissionSnapShot");
240 }
241
PostTask(InnerTask && task,std::string name,EventPriority priority)242 void WindowInnerManager::PostTask(InnerTask &&task, std::string name, EventPriority priority)
243 {
244 if (eventHandler_ == nullptr) {
245 WLOGFE("listener handler is nullptr");
246 return;
247 }
248 bool ret = eventHandler_->PostTask(task, "wms:" + name, 0, priority); // 0 is task delay time
249 if (!ret) {
250 WLOGFE("post listener callback task failed.");
251 return;
252 }
253 return;
254 }
255
GetPid()256 pid_t WindowInnerManager::GetPid()
257 {
258 return pid_;
259 }
260
SetInputEventConsumer()261 void WindowInnerManager::SetInputEventConsumer()
262 {
263 if (moveDragController_ == nullptr) {
264 return;
265 }
266 moveDragController_->SetInputEventConsumer();
267 }
268
NotifyDisplayLimitRectChange(const std::map<DisplayId,Rect> & limitRectMap)269 void WindowInnerManager::NotifyDisplayLimitRectChange(const std::map<DisplayId, Rect>& limitRectMap)
270 {
271 if (moveDragController_ == nullptr) {
272 return;
273 }
274 moveDragController_->HandleDisplayLimitRectChange(limitRectMap);
275 }
276
NotifyServerReadyToMoveOrDrag(uint32_t windowId,sptr<WindowProperty> & windowProperty,sptr<MoveDragProperty> & moveDragProperty)277 bool WindowInnerManager::NotifyServerReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty,
278 sptr<MoveDragProperty>& moveDragProperty)
279 {
280 if (moveDragController_->GetActiveWindowId() != INVALID_WINDOW_ID) {
281 WLOGFW("Is already in dragging or moving state, invalid operation");
282 return false;
283 }
284 moveDragController_->HandleReadyToMoveOrDrag(windowId, windowProperty, moveDragProperty);
285 WLOGI("NotifyServerReadyToMoveOrDrag, windowId: %{public}u", windowId);
286 return true;
287 }
288
NotifyWindowEndUpMovingOrDragging(uint32_t windowId)289 void WindowInnerManager::NotifyWindowEndUpMovingOrDragging(uint32_t windowId)
290 {
291 if (moveDragController_->GetActiveWindowId() != windowId) {
292 return;
293 }
294 moveDragController_->HandleEndUpMovingOrDragging(windowId);
295 WLOGI("NotifyWindowEndUpMovingOrDragging, windowId: %{public}u", windowId);
296 }
297
NotifyWindowRemovedOrDestroyed(uint32_t windowId)298 void WindowInnerManager::NotifyWindowRemovedOrDestroyed(uint32_t windowId)
299 {
300 if (moveDragController_->GetActiveWindowId() != windowId) {
301 return;
302 }
303 moveDragController_->HandleWindowRemovedOrDestroyed(windowId);
304 WLOGI("NotifyWindowRemovedOrDestroyed, windowId: %{public}u", windowId);
305 }
306
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)307 void WindowInnerManager::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
308 {
309 uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
310 if (moveDragController_->GetActiveWindowId() != windowId ||
311 moveDragController_->GetActiveWindowId() == INVALID_WINDOW_ID) {
312 WLOGFE("active winId or inputEvent winId is invalid, windowId: %{public}u, activeWinId: %{public}u",
313 windowId, moveDragController_->GetActiveWindowId());
314 return;
315 }
316 moveDragController_->ConsumePointerEvent(pointerEvent);
317 }
318
StartWindowInfoReportLoop()319 void WindowInnerManager::StartWindowInfoReportLoop()
320 {
321 if (isReportTaskStart_ || eventHandler_ == nullptr) {
322 return;
323 }
324 auto task = [this]() {
325 WindowInfoReporter::GetInstance().ReportRecordedInfos();
326 isReportTaskStart_ = false;
327 StartWindowInfoReportLoop();
328 };
329 int64_t delayTime = 1000 * 60 * 60; // an hour.
330 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
331 if (!ret) {
332 TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "post listener callback task failed. the task name is WindowInfoReport");
333 return;
334 }
335 isReportTaskStart_ = true;
336 }
337
SetWindowRoot(const sptr<WindowRoot> & windowRoot)338 void WindowInnerManager::SetWindowRoot(const sptr<WindowRoot>& windowRoot)
339 {
340 if (moveDragController_ != nullptr) {
341 moveDragController_->SetWindowRoot(windowRoot);
342 }
343 }
344 } // Rosen
345 } // OHOS