• 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; }, "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