1 /*
2 * Copyright (c) 2021-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 "foundation/windowmanager/interfaces/innerkits/wm/window_manager.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20
21 #include "window_adapter.h"
22 #include "window_manager_agent.h"
23 #include "window_manager_hilog.h"
24 #include "wm_common.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowManager"};
30 }
31
Marshalling(Parcel & parcel) const32 bool WindowVisibilityInfo::Marshalling(Parcel &parcel) const
33 {
34 return parcel.WriteUint32(windowId_) && parcel.WriteInt32(pid_) &&
35 parcel.WriteInt32(uid_) && parcel.WriteBool(isVisible_);
36 }
37
Unmarshalling(Parcel & parcel)38 WindowVisibilityInfo* WindowVisibilityInfo::Unmarshalling(Parcel &parcel)
39 {
40 WindowVisibilityInfo* windowVisibilityInfo = new WindowVisibilityInfo();
41 bool res = parcel.ReadUint32(windowVisibilityInfo->windowId_) && parcel.ReadInt32(windowVisibilityInfo->pid_) &&
42 parcel.ReadInt32(windowVisibilityInfo->uid_) && parcel.ReadBool(windowVisibilityInfo->isVisible_);
43 if (!res) {
44 delete windowVisibilityInfo;
45 return nullptr;
46 }
47 return windowVisibilityInfo;
48 }
49
Marshalling(Parcel & parcel) const50 bool WindowInfo::Marshalling(Parcel &parcel) const
51 {
52 return parcel.WriteInt32(wid_) && parcel.WriteUint32(windowRect_.width_) &&
53 parcel.WriteUint32(windowRect_.height_) && parcel.WriteInt32(windowRect_.posX_) &&
54 parcel.WriteInt32(windowRect_.posY_) && parcel.WriteBool(focused_) &&
55 parcel.WriteUint32(static_cast<uint32_t>(mode_)) && parcel.WriteUint32(static_cast<uint32_t>(type_));
56 }
57
Unmarshalling(Parcel & parcel)58 WindowInfo* WindowInfo::Unmarshalling(Parcel &parcel)
59 {
60 WindowInfo* windowInfo = new (std::nothrow) WindowInfo();
61 if (windowInfo == nullptr) {
62 return nullptr;
63 }
64 bool res = parcel.ReadInt32(windowInfo->wid_) && parcel.ReadUint32(windowInfo->windowRect_.width_) &&
65 parcel.ReadUint32(windowInfo->windowRect_.height_) && parcel.ReadInt32(windowInfo->windowRect_.posX_) &&
66 parcel.ReadInt32(windowInfo->windowRect_.posY_) && parcel.ReadBool(windowInfo->focused_);
67 if (!res) {
68 delete windowInfo;
69 return nullptr;
70 }
71 windowInfo->mode_ = static_cast<WindowMode>(parcel.ReadUint32());
72 windowInfo->type_ = static_cast<WindowType>(parcel.ReadUint32());
73 return windowInfo;
74 }
75
Marshalling(Parcel & parcel) const76 bool AccessibilityWindowInfo::Marshalling(Parcel &parcel) const
77 {
78 return parcel.WriteParcelable(currentWindowInfo_) && VectorMarshalling(parcel);
79 }
80
Unmarshalling(Parcel & parcel)81 AccessibilityWindowInfo* AccessibilityWindowInfo::Unmarshalling(Parcel &parcel)
82 {
83 AccessibilityWindowInfo* accessibilityWindowInfo = new AccessibilityWindowInfo();
84 accessibilityWindowInfo->currentWindowInfo_ = parcel.ReadParcelable<WindowInfo>();
85 VectorUnmarshalling(parcel, accessibilityWindowInfo);
86 return accessibilityWindowInfo;
87 }
88
VectorMarshalling(Parcel & parcel) const89 bool AccessibilityWindowInfo::VectorMarshalling(Parcel& parcel) const
90 {
91 auto size = windowList_.size();
92 if (!parcel.WriteUint32(static_cast<uint32_t>(size))) {
93 return false;
94 }
95 for (auto window : windowList_) {
96 if (!parcel.WriteParcelable(window)) {
97 return false;
98 }
99 }
100 return true;
101 }
102
VectorUnmarshalling(Parcel & parcel,AccessibilityWindowInfo * windowInfo)103 void AccessibilityWindowInfo::VectorUnmarshalling(Parcel& parcel, AccessibilityWindowInfo* windowInfo)
104 {
105 std::vector<sptr<WindowInfo>> windows;
106 uint32_t size = parcel.ReadUint32();
107 for (uint32_t i = 0; i < size; i++) {
108 WindowInfo* window = parcel.ReadParcelable<WindowInfo>();
109 if (!window) {
110 WLOGE("ReadParcelable Failed!");
111 return;
112 }
113 windowInfo->windowList_.emplace_back(window);
114 }
115 }
116
Marshalling(Parcel & parcel) const117 bool FocusChangeInfo::Marshalling(Parcel &parcel) const
118 {
119 return parcel.WriteUint32(windowId_) && parcel.WriteUint64(displayId_) &&
120 parcel.WriteInt32(pid_) && parcel.WriteInt32(uid_) &&
121 parcel.WriteUint32(static_cast<uint32_t>(windowType_));
122 }
123
Unmarshalling(Parcel & parcel)124 FocusChangeInfo* FocusChangeInfo::Unmarshalling(Parcel &parcel)
125 {
126 FocusChangeInfo* focusChangeInfo = new FocusChangeInfo();
127 bool res = parcel.ReadUint32(focusChangeInfo->windowId_) && parcel.ReadUint64(focusChangeInfo->displayId_) &&
128 parcel.ReadInt32(focusChangeInfo->pid_) && parcel.ReadInt32(focusChangeInfo->uid_);
129 if (!res) {
130 delete focusChangeInfo;
131 return nullptr;
132 }
133 focusChangeInfo->windowType_ = static_cast<WindowType>(parcel.ReadUint32());
134 return focusChangeInfo;
135 }
136
137 WM_IMPLEMENT_SINGLE_INSTANCE(WindowManager)
138
139 class WindowManager::Impl {
140 public:
141 void NotifyFocused(uint32_t windowId, const sptr<IRemoteObject>& abilityToken,
142 WindowType windowType, DisplayId displayId) const;
143 void NotifyUnfocused(uint32_t windowId, const sptr<IRemoteObject>& abilityToken,
144 WindowType windowType, DisplayId displayId) const;
145 void NotifyFocused(const sptr<FocusChangeInfo>& focusChangeInfo) const;
146 void NotifyUnfocused(const sptr<FocusChangeInfo>& focusChangeInfo) const;
147 void NotifySystemBarChanged(DisplayId displayId, const SystemBarRegionTints& tints) const;
148 void NotifyAccessibilityWindowInfo(const sptr<AccessibilityWindowInfo>& windowInfo, WindowUpdateType type) const;
149 void NotifyWindowVisibilityInfoChanged(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const;
150 static inline SingletonDelegator<WindowManager> delegator_;
151
152 std::recursive_mutex mutex_;
153 std::vector<sptr<IFocusChangedListener>> focusChangedListeners_;
154 sptr<WindowManagerAgent> focusChangedListenerAgent_;
155 std::vector<sptr<ISystemBarChangedListener>> systemBarChangedListeners_;
156 sptr<WindowManagerAgent> systemBarChangedListenerAgent_;
157 std::vector<sptr<IWindowUpdateListener>> windowUpdateListeners_;
158 sptr<WindowManagerAgent> windowUpdateListenerAgent_;
159 std::vector<sptr<IVisibilityChangedListener>> windowVisibilityListeners_;
160 sptr<WindowManagerAgent> windowVisibilityListenerAgent_;
161 };
162
NotifyFocused(const sptr<FocusChangeInfo> & focusChangeInfo) const163 void WindowManager::Impl::NotifyFocused(const sptr<FocusChangeInfo>& focusChangeInfo) const
164 {
165 WLOGFI("NotifyFocused [%{public}u; %{public}" PRIu64"; %{public}d; %{public}d; %{public}u; %{public}p]",
166 focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_,
167 static_cast<uint32_t>(focusChangeInfo->windowType_), focusChangeInfo->abilityToken_.GetRefPtr());
168 for (auto& listener : focusChangedListeners_) {
169 listener->OnFocused(focusChangeInfo);
170 }
171 }
172
NotifyUnfocused(const sptr<FocusChangeInfo> & focusChangeInfo) const173 void WindowManager::Impl::NotifyUnfocused(const sptr<FocusChangeInfo>& focusChangeInfo) const
174 {
175 WLOGFI("NotifyUnfocused [%{public}u; %{public}" PRIu64"; %{public}d; %{public}d; %{public}u; %{public}p]",
176 focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_,
177 static_cast<uint32_t>(focusChangeInfo->windowType_), focusChangeInfo->abilityToken_.GetRefPtr());
178 for (auto& listener : focusChangedListeners_) {
179 listener->OnUnfocused(focusChangeInfo);
180 }
181 }
182
NotifySystemBarChanged(DisplayId displayId,const SystemBarRegionTints & tints) const183 void WindowManager::Impl::NotifySystemBarChanged(DisplayId displayId, const SystemBarRegionTints& tints) const
184 {
185 for (auto tint : tints) {
186 WLOGFI("type:%{public}d, enable:%{public}d," \
187 "backgroundColor:%{public}x, contentColor:%{public}x " \
188 "region:[%{public}d, %{public}d, %{public}d, %{public}d]",
189 tint.type_, tint.prop_.enable_, tint.prop_.backgroundColor_, tint.prop_.contentColor_,
190 tint.region_.posX_, tint.region_.posY_, tint.region_.width_, tint.region_.height_);
191 }
192 for (auto& listener : systemBarChangedListeners_) {
193 listener->OnSystemBarPropertyChange(displayId, tints);
194 }
195 }
196
NotifyAccessibilityWindowInfo(const sptr<AccessibilityWindowInfo> & windowInfo,WindowUpdateType type) const197 void WindowManager::Impl::NotifyAccessibilityWindowInfo(const sptr<AccessibilityWindowInfo>& windowInfo,
198 WindowUpdateType type) const
199 {
200 WLOGFI("NotifyAccessibilityWindowInfo: wid[%{public}d],width[%{public}d], \
201 height[%{public}d],positionX[%{public}d],positionY[%{public}d],\
202 isFocused[%{public}d],mode[%{public}d],type[%{public}d]",
203 windowInfo->currentWindowInfo_->wid_, windowInfo->currentWindowInfo_->windowRect_.width_,
204 windowInfo->currentWindowInfo_->windowRect_.height_,
205 windowInfo->currentWindowInfo_->windowRect_.posX_, windowInfo->currentWindowInfo_->windowRect_.posY_,
206 windowInfo->currentWindowInfo_->focused_, windowInfo->currentWindowInfo_->mode_,
207 windowInfo->currentWindowInfo_->type_);
208 for (auto& listener : windowUpdateListeners_) {
209 listener->OnWindowUpdate(windowInfo, type);
210 }
211 }
212
NotifyWindowVisibilityInfoChanged(const std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos) const213 void WindowManager::Impl::NotifyWindowVisibilityInfoChanged(
214 const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const
215 {
216 for (auto& listener : windowVisibilityListeners_) {
217 listener->OnWindowVisibilityChanged(windowVisibilityInfos);
218 }
219 }
220
WindowManager()221 WindowManager::WindowManager() : pImpl_(std::make_unique<Impl>())
222 {
223 }
224
~WindowManager()225 WindowManager::~WindowManager()
226 {
227 }
228
RegisterFocusChangedListener(const sptr<IFocusChangedListener> & listener)229 void WindowManager::RegisterFocusChangedListener(const sptr<IFocusChangedListener>& listener)
230 {
231 if (listener == nullptr) {
232 WLOGFE("listener could not be null");
233 return;
234 }
235
236 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
237 pImpl_->focusChangedListeners_.push_back(listener);
238 if (pImpl_->focusChangedListenerAgent_ == nullptr) {
239 pImpl_->focusChangedListenerAgent_ = new WindowManagerAgent();
240 SingletonContainer::Get<WindowAdapter>().RegisterWindowManagerAgent(
241 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS, pImpl_->focusChangedListenerAgent_);
242 }
243 }
244
UnregisterFocusChangedListener(const sptr<IFocusChangedListener> & listener)245 void WindowManager::UnregisterFocusChangedListener(const sptr<IFocusChangedListener>& listener)
246 {
247 if (listener == nullptr) {
248 WLOGFE("listener could not be null");
249 return;
250 }
251
252 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
253 auto iter = std::find(pImpl_->focusChangedListeners_.begin(), pImpl_->focusChangedListeners_.end(), listener);
254 if (iter == pImpl_->focusChangedListeners_.end()) {
255 WLOGFE("could not find this listener");
256 return;
257 }
258 pImpl_->focusChangedListeners_.erase(iter);
259 if (pImpl_->focusChangedListeners_.empty() && pImpl_->focusChangedListenerAgent_ != nullptr) {
260 SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
261 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_FOCUS, pImpl_->focusChangedListenerAgent_);
262 pImpl_->focusChangedListenerAgent_ = nullptr;
263 }
264 }
265
RegisterSystemBarChangedListener(const sptr<ISystemBarChangedListener> & listener)266 void WindowManager::RegisterSystemBarChangedListener(const sptr<ISystemBarChangedListener>& listener)
267 {
268 if (listener == nullptr) {
269 WLOGFE("listener could not be null");
270 return;
271 }
272
273 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
274 pImpl_->systemBarChangedListeners_.push_back(listener);
275 if (pImpl_->systemBarChangedListenerAgent_ == nullptr) {
276 pImpl_->systemBarChangedListenerAgent_ = new WindowManagerAgent();
277 SingletonContainer::Get<WindowAdapter>().RegisterWindowManagerAgent(
278 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR, pImpl_->systemBarChangedListenerAgent_);
279 }
280 }
281
UnregisterSystemBarChangedListener(const sptr<ISystemBarChangedListener> & listener)282 void WindowManager::UnregisterSystemBarChangedListener(const sptr<ISystemBarChangedListener>& listener)
283 {
284 if (listener == nullptr) {
285 WLOGFE("listener could not be null");
286 return;
287 }
288
289 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
290 auto iter = std::find(pImpl_->systemBarChangedListeners_.begin(), pImpl_->systemBarChangedListeners_.end(),
291 listener);
292 if (iter == pImpl_->systemBarChangedListeners_.end()) {
293 WLOGFE("could not find this listener");
294 return;
295 }
296 pImpl_->systemBarChangedListeners_.erase(iter);
297 if (pImpl_->systemBarChangedListeners_.empty() && pImpl_->systemBarChangedListenerAgent_ != nullptr) {
298 SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
299 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR, pImpl_->systemBarChangedListenerAgent_);
300 pImpl_->systemBarChangedListenerAgent_ = nullptr;
301 }
302 }
303
MinimizeAllAppWindows(DisplayId displayId)304 void WindowManager::MinimizeAllAppWindows(DisplayId displayId)
305 {
306 WLOGFI("displayId %{public}" PRIu64"", displayId);
307 SingletonContainer::Get<WindowAdapter>().MinimizeAllAppWindows(displayId);
308 }
309
SetWindowLayoutMode(WindowLayoutMode mode,DisplayId displayId)310 WMError WindowManager::SetWindowLayoutMode(WindowLayoutMode mode, DisplayId displayId)
311 {
312 WLOGFI("set window layout mode: %{public}u, displayId %{public}" PRIu64"", mode, displayId);
313 WMError ret = SingletonContainer::Get<WindowAdapter>().SetWindowLayoutMode(displayId, mode);
314 if (ret != WMError::WM_OK) {
315 WLOGFE("set layout mode failed");
316 }
317 return ret;
318 }
319
RegisterWindowUpdateListener(const sptr<IWindowUpdateListener> & listener)320 void WindowManager::RegisterWindowUpdateListener(const sptr<IWindowUpdateListener> &listener)
321 {
322 if (listener == nullptr) {
323 WLOGFE("listener could not be null");
324 return;
325 }
326 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
327 pImpl_->windowUpdateListeners_.emplace_back(listener);
328 if (pImpl_->windowUpdateListenerAgent_ == nullptr) {
329 pImpl_->windowUpdateListenerAgent_ = new WindowManagerAgent();
330 SingletonContainer::Get<WindowAdapter>().RegisterWindowManagerAgent(
331 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE, pImpl_->windowUpdateListenerAgent_);
332 }
333 }
334
UnregisterWindowUpdateListener(const sptr<IWindowUpdateListener> & listener)335 void WindowManager::UnregisterWindowUpdateListener(const sptr<IWindowUpdateListener>& listener)
336 {
337 if (listener == nullptr) {
338 WLOGFE("listener could not be null");
339 return;
340 }
341 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
342 auto iter = std::find(pImpl_->windowUpdateListeners_.begin(), pImpl_->windowUpdateListeners_.end(),
343 listener);
344 if (iter == pImpl_->windowUpdateListeners_.end()) {
345 WLOGFE("could not find this listener");
346 return;
347 }
348 pImpl_->windowUpdateListeners_.erase(iter);
349 if (pImpl_->windowUpdateListeners_.empty() && pImpl_->windowUpdateListenerAgent_ != nullptr) {
350 SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
351 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE, pImpl_->windowUpdateListenerAgent_);
352 pImpl_->windowUpdateListenerAgent_ = nullptr;
353 }
354 }
355
RegisterVisibilityChangedListener(const sptr<IVisibilityChangedListener> & listener)356 void WindowManager::RegisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener)
357 {
358 if (listener == nullptr) {
359 WLOGFE("listener could not be null");
360 return;
361 }
362 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
363 pImpl_->windowVisibilityListeners_.emplace_back(listener);
364 if (pImpl_->windowVisibilityListenerAgent_ == nullptr) {
365 pImpl_->windowVisibilityListenerAgent_ = new WindowManagerAgent();
366 SingletonContainer::Get<WindowAdapter>().RegisterWindowManagerAgent(
367 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
368 pImpl_->windowVisibilityListenerAgent_);
369 }
370 }
371
UnregisterVisibilityChangedListener(const sptr<IVisibilityChangedListener> & listener)372 void WindowManager::UnregisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener)
373 {
374 if (listener == nullptr) {
375 return;
376 }
377 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
378 pImpl_->windowVisibilityListeners_.erase(std::remove_if(pImpl_->windowVisibilityListeners_.begin(),
379 pImpl_->windowVisibilityListeners_.end(), [listener](sptr<IVisibilityChangedListener> registeredListener) {
380 return registeredListener == listener;
381 }), pImpl_->windowVisibilityListeners_.end());
382
383 if (pImpl_->windowVisibilityListeners_.empty() && pImpl_->windowVisibilityListenerAgent_ != nullptr) {
384 SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
385 WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
386 pImpl_->windowVisibilityListenerAgent_);
387 pImpl_->windowVisibilityListenerAgent_ = nullptr;
388 }
389 }
390
UpdateFocusChangeInfo(const sptr<FocusChangeInfo> & focusChangeInfo,bool focused) const391 void WindowManager::UpdateFocusChangeInfo(const sptr<FocusChangeInfo>& focusChangeInfo, bool focused) const
392 {
393 WLOGFI("window focus change: %{public}d, id: %{public}u", focused, focusChangeInfo->windowId_);
394 if (focused) {
395 pImpl_->NotifyFocused(focusChangeInfo);
396 } else {
397 pImpl_->NotifyUnfocused(focusChangeInfo);
398 }
399 }
400
UpdateSystemBarRegionTints(DisplayId displayId,const SystemBarRegionTints & tints) const401 void WindowManager::UpdateSystemBarRegionTints(DisplayId displayId,
402 const SystemBarRegionTints& tints) const
403 {
404 pImpl_->NotifySystemBarChanged(displayId, tints);
405 }
406
NotifyAccessibilityWindowInfo(const sptr<AccessibilityWindowInfo> & windowInfo,WindowUpdateType type)407 void WindowManager::NotifyAccessibilityWindowInfo(const sptr<AccessibilityWindowInfo>& windowInfo,
408 WindowUpdateType type)
409 {
410 pImpl_->NotifyAccessibilityWindowInfo(windowInfo, type);
411 }
412
UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>> & windowVisibilityInfos) const413 void WindowManager::UpdateWindowVisibilityInfo(
414 const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const
415 {
416 pImpl_->NotifyWindowVisibilityInfoChanged(windowVisibilityInfos);
417 }
418 } // namespace Rosen
419 } // namespace OHOS
420