• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowInnerManager"};
27 }
WM_IMPLEMENT_SINGLE_INSTANCE(WindowInnerManager)28 WM_IMPLEMENT_SINGLE_INSTANCE(WindowInnerManager)
29 
30 WindowInnerManager::WindowInnerManager() : eventHandler_(nullptr), eventLoop_(nullptr),
31     state_(InnerWMRunningState::STATE_NOT_START)
32 {
33 }
34 
~WindowInnerManager()35 WindowInnerManager::~WindowInnerManager()
36 {
37     Stop();
38 }
39 
Init()40 bool WindowInnerManager::Init()
41 {
42     // create handler for inner command at server
43     eventLoop_ = AppExecFwk::EventRunner::Create(INNER_WM_THREAD_NAME);
44     if (eventLoop_ == nullptr) {
45         return false;
46     }
47     eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
48     if (eventHandler_ == nullptr) {
49         return false;
50     }
51 
52     eventHandler_->PostTask([]() { MemoryGuard cacheGuard; }, AppExecFwk::EventQueue::Priority::IMMEDIATE);
53     moveDragController_ = new MoveDragController();
54     if (!moveDragController_->Init()) {
55         WLOGFE("Init window drag controller failed");
56         return false;
57     }
58 
59     WLOGFI("init window inner manager service success.");
60     return true;
61 }
62 
Start(bool enableRecentholder)63 void WindowInnerManager::Start(bool enableRecentholder)
64 {
65     isRecentHolderEnable_ = enableRecentholder;
66     if (state_ == InnerWMRunningState::STATE_RUNNING) {
67         WLOGFI("window inner manager service has already started.");
68     }
69     if (!Init()) {
70         WLOGFI("failed to init window inner manager service.");
71         return;
72     }
73     state_ = InnerWMRunningState::STATE_RUNNING;
74     eventLoop_->Run();
75 
76     pid_ = getpid();
77     WLOGFI("window inner manager service start success.");
78 }
79 
Stop()80 void WindowInnerManager::Stop()
81 {
82     WLOGFI("stop window inner manager service.");
83     if (eventLoop_ != nullptr) {
84         eventLoop_->Stop();
85         eventLoop_.reset();
86     }
87     if (eventHandler_ != nullptr) {
88         eventHandler_.reset();
89     }
90     if (moveDragController_ != nullptr) {
91         moveDragController_->Stop();
92     }
93     state_ = InnerWMRunningState::STATE_NOT_START;
94 }
95 
CreateInnerWindow(std::string name,DisplayId displayId,Rect rect,WindowType type,WindowMode mode)96 void WindowInnerManager::CreateInnerWindow(std::string name, DisplayId displayId, Rect rect,
97     WindowType type, WindowMode mode)
98 {
99     bool recentHolderWindowFlag = isRecentHolderEnable_;
100     auto task = [name, displayId, rect, mode, type, recentHolderWindowFlag]() {
101         switch (type) {
102             case WindowType::WINDOW_TYPE_PLACEHOLDER: {
103                 if (recentHolderWindowFlag) {
104                     PlaceHolderWindow::GetInstance().Create(name, displayId, rect, mode);
105                 }
106                 break;
107             }
108             default:
109                 break;
110         }
111     };
112     PostTask(task, "CreateInnerWindow");
113     return;
114 }
115 
DestroyInnerWindow(DisplayId displayId,WindowType type)116 void WindowInnerManager::DestroyInnerWindow(DisplayId displayId, WindowType type)
117 {
118     bool recentHolderWindowFlag = isRecentHolderEnable_;
119     auto task = [type, recentHolderWindowFlag]() {
120         switch (type) {
121             case WindowType::WINDOW_TYPE_PLACEHOLDER: {
122                 if (recentHolderWindowFlag) {
123                     PlaceHolderWindow::GetInstance().Destroy();
124                 }
125                 break;
126             }
127             default:
128                 break;
129         }
130     };
131     PostTask(task, "DestroyInnerWindow");
132     return;
133 }
134 
UpdateInnerWindow(DisplayId displayId,WindowType type,uint32_t width,uint32_t height)135 void WindowInnerManager::UpdateInnerWindow(DisplayId displayId, WindowType type, uint32_t width, uint32_t height)
136 {
137     bool recentHolderWindowFlag = isRecentHolderEnable_;
138     auto task = [type, width, height, recentHolderWindowFlag]() {
139         switch (type) {
140             case WindowType::WINDOW_TYPE_PLACEHOLDER: {
141                 if (recentHolderWindowFlag) {
142                     PlaceHolderWindow::GetInstance().Update(width, height);
143                 }
144                 break;
145             }
146             default:
147                 break;
148         }
149     };
150     PostTask(task, "UpdateInnerWindow");
151     return;
152 }
153 
MinimizeAbility(const wptr<WindowNode> & node,bool isFromUser)154 void WindowInnerManager::MinimizeAbility(const wptr<WindowNode> &node, bool isFromUser)
155 {
156     // asynchronously calls the MinimizeAbility of AbilityManager
157     auto weakNode = node.promote();
158     if (weakNode == nullptr) {
159         WLOGFE("minimize ability failed.");
160         return;
161     }
162     wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
163     WLOGFD("minimize window %{public}u,  isfromuser: %{public}d", weakNode->GetWindowId(), isFromUser);
164     auto task = [weakToken, isFromUser]() {
165         auto token = weakToken.promote();
166         if (token == nullptr) {
167             WLOGE("minimize ability failed, because window token is nullptr.");
168             return;
169         }
170         AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(token, isFromUser);
171     };
172     PostTask(task, "MinimizeAbility");
173 }
174 
TerminateAbility(const wptr<WindowNode> & node)175 void WindowInnerManager::TerminateAbility(const wptr<WindowNode> &node)
176 {
177     // asynchronously calls the TerminateAbility of AbilityManager
178     auto weakNode = node.promote();
179     if (weakNode == nullptr) {
180         WLOGFE("terminate ability failed.");
181         return;
182     }
183     wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
184     WLOGFD("terminate window %{public}u", weakNode->GetWindowId());
185     auto task = [weakToken]() {
186         auto token = weakToken.promote();
187         if (token == nullptr) {
188             WLOGE("terminate ability failed, because window token is nullptr.");
189             return;
190         }
191         AAFwk::Want resultWant;
192         AAFwk::AbilityManagerClient::GetInstance()->TerminateAbility(token, -1, &resultWant);
193     };
194     PostTask(task, "TerminateAbility");
195 }
196 
CloseAbility(const wptr<WindowNode> & node)197 void WindowInnerManager::CloseAbility(const wptr<WindowNode> &node)
198 {
199     // asynchronously calls the CloseAbility of AbilityManager
200     auto weakNode = node.promote();
201     if (weakNode == nullptr) {
202         WLOGFE("close ability failed.");
203         return;
204     }
205     wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
206     WLOGFD("close window %{public}u", weakNode->GetWindowId());
207     auto task = [weakToken]() {
208         auto token = weakToken.promote();
209         if (token == nullptr) {
210             WLOGE("close ability failed, because window token is nullptr.");
211             return;
212         }
213         AAFwk::Want resultWant;
214         AAFwk::AbilityManagerClient::GetInstance()->CloseAbility(token);
215     };
216     PostTask(task, "CloseAbility");
217 }
218 
CompleteFirstFrameDrawing(const wptr<WindowNode> & node)219 void WindowInnerManager::CompleteFirstFrameDrawing(const wptr<WindowNode> &node)
220 {
221     // asynchronously calls the CloseAbility of AbilityManager
222     auto weakNode = node.promote();
223     if (weakNode == nullptr) {
224         WLOGFE("CompleteFirstFrameDrawing failed.");
225         return;
226     }
227     wptr<IRemoteObject> weakToken(weakNode->abilityToken_);
228     WLOGFD("CompleteFirstFrameDrawing %{public}u", weakNode->GetWindowId());
229     auto task = [weakToken]() {
230         auto token = weakToken.promote();
231         if (token == nullptr) {
232             WLOGE("CompleteFirstFrameDrawing failed, because window token is nullptr.");
233             return;
234         }
235         AAFwk::AbilityManagerClient::GetInstance()->CompleteFirstFrameDrawing(token);
236     };
237     PostTask(task, "CompleteFirstFrameDrawing");
238 }
239 
PostTask(InnerTask && task,std::string name,EventPriority priority)240 void WindowInnerManager::PostTask(InnerTask &&task, std::string name, EventPriority priority)
241 {
242     if (eventHandler_ == nullptr) {
243         WLOGFE("listener handler is nullptr");
244         return;
245     }
246     bool ret = eventHandler_->PostTask(task, name, 0, priority); // 0 is task delay time
247     if (!ret) {
248         WLOGFE("post listener callback task failed.");
249         return;
250     }
251     return;
252 }
253 
GetPid()254 pid_t WindowInnerManager::GetPid()
255 {
256     return pid_;
257 }
258 
SetInputEventConsumer()259 void WindowInnerManager::SetInputEventConsumer()
260 {
261     if (moveDragController_ == nullptr) {
262         return;
263     }
264     moveDragController_->SetInputEventConsumer();
265 }
266 
NotifyDisplayChange(const std::map<DisplayId,Rect> & displayRectMap)267 void WindowInnerManager::NotifyDisplayChange(const std::map<DisplayId, Rect>& displayRectMap)
268 {
269     if (moveDragController_ == nullptr) {
270         return;
271     }
272     moveDragController_->HandleDisplayChange(displayRectMap);
273 }
274 
NotifyServerReadyToMoveOrDrag(uint32_t windowId,sptr<WindowProperty> & windowProperty,sptr<MoveDragProperty> & moveDragProperty)275 bool WindowInnerManager::NotifyServerReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty,
276     sptr<MoveDragProperty>& moveDragProperty)
277 {
278     if (moveDragController_->GetActiveWindowId() != INVALID_WINDOW_ID) {
279         WLOGFW("Is already in dragging or moving state, invalid operation");
280         return false;
281     }
282     moveDragController_->HandleReadyToMoveOrDrag(windowId, windowProperty, moveDragProperty);
283     WLOGFI("NotifyServerReadyToMoveOrDrag, windowId: %{public}u", windowId);
284     return true;
285 }
286 
NotifyWindowEndUpMovingOrDragging(uint32_t windowId)287 void WindowInnerManager::NotifyWindowEndUpMovingOrDragging(uint32_t windowId)
288 {
289     if (moveDragController_->GetActiveWindowId() != windowId) {
290         return;
291     }
292     moveDragController_->HandleEndUpMovingOrDragging(windowId);
293     WLOGFI("NotifyWindowEndUpMovingOrDragging, windowId: %{public}u", windowId);
294 }
295 
NotifyWindowRemovedOrDestroyed(uint32_t windowId)296 void WindowInnerManager::NotifyWindowRemovedOrDestroyed(uint32_t windowId)
297 {
298     if (moveDragController_->GetActiveWindowId() != windowId) {
299         return;
300     }
301     moveDragController_->HandleWindowRemovedOrDestroyed(windowId);
302     WLOGFI("NotifyWindowRemovedOrDestroyed, windowId: %{public}u", windowId);
303 }
304 
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)305 void WindowInnerManager::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
306 {
307     uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
308     if (moveDragController_->GetActiveWindowId() != windowId ||
309         moveDragController_->GetActiveWindowId() == INVALID_WINDOW_ID) {
310         WLOGFE("active winId or inputEvent winId is invalid, windowId: %{public}u, activeWinId: %{public}u",
311             windowId, moveDragController_->GetActiveWindowId());
312         return;
313     }
314     moveDragController_->ConsumePointerEvent(pointerEvent);
315 }
316 } // Rosen
317 } // OHOS
318