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