• 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 "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