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