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 #include "screen_manager.h"
16
17 #include <map>
18 #include <vector>
19
20 #include <transaction/rs_interfaces.h>
21
22 #include "display_manager_adapter.h"
23 #include "display_manager_agent_default.h"
24 #include "singleton_delegator.h"
25 #include "window_manager_hilog.h"
26
27
28 namespace OHOS::Rosen {
29 namespace {
30 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "ScreenManager"};
31 const static uint32_t MAX_SCREEN_SIZE = 32;
32 }
33 class ScreenManager::Impl : public RefBase {
34 public:
35 Impl() = default;
36 ~Impl();
37 static inline SingletonDelegator<ScreenManager> delegator;
38 bool RegisterScreenListener(sptr<IScreenListener> listener);
39 bool UnregisterScreenListener(sptr<IScreenListener> listener);
40 bool RegisterScreenGroupListener(sptr<IScreenGroupListener> listener);
41 bool UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener);
42 sptr<Screen> GetScreen(ScreenId screenId);
43 sptr<ScreenGroup> GetScreenGroup(ScreenId screenId);
44 std::vector<sptr<Screen>> GetAllScreens();
45
46 private:
47 void NotifyScreenConnect(sptr<ScreenInfo> info);
48 void NotifyScreenDisconnect(ScreenId);
49 void NotifyScreenChange(const sptr<ScreenInfo>& screenInfo);
50 void NotifyScreenChange(const std::vector<sptr<ScreenInfo>>& screenInfos);
51 bool UpdateScreenInfoLocked(sptr<ScreenInfo>);
52
53 class ScreenManagerListener;
54 sptr<ScreenManagerListener> screenManagerListener_;
55 std::map<ScreenId, sptr<Screen>> screenMap_;
56 std::map<ScreenId, sptr<ScreenGroup>> screenGroupMap_;
57 std::recursive_mutex mutex_;
58 std::set<sptr<IScreenListener>> screenListeners_;
59 std::set<sptr<IScreenGroupListener>> screenGroupListeners_;
60 };
61
62 class ScreenManager::Impl::ScreenManagerListener : public DisplayManagerAgentDefault {
63 public:
ScreenManagerListener(sptr<Impl> impl)64 ScreenManagerListener(sptr<Impl> impl) : pImpl_(impl)
65 {
66 }
67
OnScreenConnect(sptr<ScreenInfo> screenInfo)68 void OnScreenConnect(sptr<ScreenInfo> screenInfo)
69 {
70 if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) {
71 WLOGFE("OnScreenConnect, screenInfo is invalid.");
72 return;
73 }
74 if (pImpl_ == nullptr) {
75 WLOGFE("OnScreenConnect, impl is nullptr.");
76 return;
77 }
78 pImpl_->NotifyScreenConnect(screenInfo);
79 for (auto listener : pImpl_->screenListeners_) {
80 listener->OnConnect(screenInfo->GetScreenId());
81 }
82 };
83
OnScreenDisconnect(ScreenId screenId)84 void OnScreenDisconnect(ScreenId screenId)
85 {
86 if (screenId == SCREEN_ID_INVALID) {
87 WLOGFE("OnScreenDisconnect, screenId is invalid.");
88 return;
89 }
90 if (pImpl_ == nullptr) {
91 WLOGFE("OnScreenDisconnect, impl is nullptr.");
92 return;
93 }
94 pImpl_->NotifyScreenDisconnect(screenId);
95 for (auto listener : pImpl_->screenListeners_) {
96 listener->OnDisconnect(screenId);
97 }
98 };
99
OnScreenChange(const sptr<ScreenInfo> & screenInfo,ScreenChangeEvent event)100 void OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)
101 {
102 if (screenInfo == nullptr) {
103 WLOGFE("OnScreenChange, screenInfo is null.");
104 return;
105 }
106 if (pImpl_ == nullptr) {
107 WLOGFE("OnScreenChange, impl is nullptr.");
108 return;
109 }
110 WLOGFD("OnScreenChange. event %{public}u", event);
111 pImpl_->NotifyScreenChange(screenInfo);
112 for (auto listener: pImpl_->screenListeners_) {
113 listener->OnChange(screenInfo->GetScreenId());
114 }
115 };
116
OnScreenGroupChange(const std::vector<sptr<ScreenInfo>> & screenInfos,ScreenGroupChangeEvent groupEvent)117 void OnScreenGroupChange(const std::vector<sptr<ScreenInfo>>& screenInfos, ScreenGroupChangeEvent groupEvent)
118 {
119 if (screenInfos.empty()) {
120 WLOGFE("OnScreenGroupChange, screenInfos is empty.");
121 return;
122 }
123 if (pImpl_ == nullptr) {
124 WLOGFE("OnScreenGroupChange, impl is nullptr.");
125 return;
126 }
127 WLOGFD("OnScreenGroupChange. event %{public}u", groupEvent);
128 pImpl_->NotifyScreenChange(screenInfos);
129 std::vector<ScreenId> screenIds;
130 for (auto screenInfo : screenInfos) {
131 if (screenInfo->GetScreenId() != SCREEN_ID_INVALID) {
132 screenIds.push_back(screenInfo->GetScreenId());
133 }
134 }
135 for (auto listener: pImpl_->screenGroupListeners_) {
136 listener->OnChange(screenIds, groupEvent);
137 }
138 };
139 private:
140 sptr<Impl> pImpl_;
141 };
WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManager)142 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManager)
143
144 ScreenManager::ScreenManager()
145 {
146 pImpl_ = new Impl();
147 }
148
~ScreenManager()149 ScreenManager::~ScreenManager()
150 {
151 }
152
~Impl()153 ScreenManager::Impl::~Impl()
154 {
155 std::lock_guard<std::recursive_mutex> lock(mutex_);
156 bool res = true;
157 if (screenManagerListener_ != nullptr) {
158 res = SingletonContainer::Get<ScreenManagerAdapter>().UnregisterDisplayManagerAgent(
159 screenManagerListener_,
160 DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
161 }
162 screenManagerListener_ = nullptr;
163 if (!res) {
164 WLOGFW("UnregisterDisplayManagerAgent SCREEN_EVENT_LISTENER failed !");
165 }
166 }
167
GetScreen(ScreenId screenId)168 sptr<Screen> ScreenManager::Impl::GetScreen(ScreenId screenId)
169 {
170 auto screenInfo = SingletonContainer::Get<ScreenManagerAdapter>().GetScreenInfo(screenId);
171 std::lock_guard<std::recursive_mutex> lock(mutex_);
172 if (!UpdateScreenInfoLocked(screenInfo)) {
173 screenMap_.erase(screenId);
174 return nullptr;
175 }
176 return screenMap_[screenId];
177 }
178
GetScreenById(ScreenId screenId)179 sptr<Screen> ScreenManager::GetScreenById(ScreenId screenId)
180 {
181 return pImpl_->GetScreen(screenId);
182 }
183
GetScreenGroup(ScreenId screenId)184 sptr<ScreenGroup> ScreenManager::Impl::GetScreenGroup(ScreenId screenId)
185 {
186 auto screenGroupInfo = SingletonContainer::Get<ScreenManagerAdapter>().GetScreenGroupInfoById(screenId);
187 std::lock_guard<std::recursive_mutex> lock(mutex_);
188 if (screenGroupInfo == nullptr) {
189 WLOGFE("screenGroupInfo is null");
190 screenGroupMap_.erase(screenId);
191 return nullptr;
192 }
193 auto iter = screenGroupMap_.find(screenId);
194 if (iter != screenGroupMap_.end() && iter->second != nullptr) {
195 WLOGFI("get screenGroup in screenGroup map");
196 iter->second->UpdateScreenGroupInfo(screenGroupInfo);
197 return iter->second;
198 }
199 sptr<ScreenGroup> screenGroup = new ScreenGroup(screenGroupInfo);
200 screenGroupMap_[screenId] = screenGroup;
201 return screenGroup;
202 }
203
GetScreenGroup(ScreenId screenId)204 sptr<ScreenGroup> ScreenManager::GetScreenGroup(ScreenId screenId)
205 {
206 return pImpl_->GetScreenGroup(screenId);
207 }
208
GetAllScreens()209 std::vector<sptr<Screen>> ScreenManager::Impl::GetAllScreens()
210 {
211 auto screenInfos = SingletonContainer::Get<ScreenManagerAdapter>().GetAllScreenInfos();
212 std::vector<sptr<Screen>> screens;
213 std::lock_guard<std::recursive_mutex> lock(mutex_);
214 for (auto info: screenInfos) {
215 if (UpdateScreenInfoLocked(info)) {
216 screens.emplace_back(screenMap_[info->GetScreenId()]);
217 }
218 }
219 screenMap_.clear();
220 for (auto screen: screens) {
221 screenMap_.insert(std::make_pair(screen->GetId(), screen));
222 }
223 return screens;
224 }
225
GetAllScreens()226 std::vector<sptr<Screen>> ScreenManager::GetAllScreens()
227 {
228 return pImpl_->GetAllScreens();
229 }
230
RegisterScreenListener(sptr<IScreenListener> listener)231 bool ScreenManager::Impl::RegisterScreenListener(sptr<IScreenListener> listener)
232 {
233 std::lock_guard<std::recursive_mutex> lock(mutex_);
234 bool ret = true;
235 if (screenManagerListener_ == nullptr) {
236 screenManagerListener_ = new ScreenManagerListener(this);
237 ret = SingletonContainer::Get<ScreenManagerAdapter>().RegisterDisplayManagerAgent(
238 screenManagerListener_,
239 DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
240 }
241 if (!ret) {
242 WLOGFW("RegisterScreenListener failed !");
243 screenManagerListener_ = nullptr;
244 } else {
245 screenListeners_.insert(listener);
246 }
247 return ret;
248 }
249
RegisterScreenListener(sptr<IScreenListener> listener)250 bool ScreenManager::RegisterScreenListener(sptr<IScreenListener> listener)
251 {
252 if (listener == nullptr) {
253 WLOGFE("RegisterScreenListener listener is nullptr.");
254 return false;
255 }
256 return pImpl_->RegisterScreenListener(listener);
257 }
258
UnregisterScreenListener(sptr<IScreenListener> listener)259 bool ScreenManager::Impl::UnregisterScreenListener(sptr<IScreenListener> listener)
260 {
261 std::lock_guard<std::recursive_mutex> lock(mutex_);
262 auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener);
263 if (iter == screenListeners_.end()) {
264 WLOGFE("could not find this listener");
265 return false;
266 }
267 bool ret = true;
268 screenListeners_.erase(iter);
269 if (screenListeners_.empty() && screenGroupListeners_.empty() && screenManagerListener_ != nullptr) {
270 ret = SingletonContainer::Get<ScreenManagerAdapter>().UnregisterDisplayManagerAgent(
271 screenManagerListener_,
272 DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
273 screenManagerListener_ = nullptr;
274 }
275 return ret;
276 }
277
UnregisterScreenListener(sptr<IScreenListener> listener)278 bool ScreenManager::UnregisterScreenListener(sptr<IScreenListener> listener)
279 {
280 if (listener == nullptr) {
281 WLOGFE("UnregisterScreenListener listener is nullptr.");
282 return false;
283 }
284 return pImpl_->UnregisterScreenListener(listener);
285 }
286
RegisterScreenGroupListener(sptr<IScreenGroupListener> listener)287 bool ScreenManager::Impl::RegisterScreenGroupListener(sptr<IScreenGroupListener> listener)
288 {
289 std::lock_guard<std::recursive_mutex> lock(mutex_);
290 bool ret = true;
291 if (screenManagerListener_ == nullptr) {
292 screenManagerListener_ = new ScreenManagerListener(this);
293 ret = SingletonContainer::Get<ScreenManagerAdapter>().RegisterDisplayManagerAgent(
294 screenManagerListener_,
295 DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
296 }
297 if (!ret) {
298 WLOGFW("RegisterScreenGroupListener failed !");
299 screenManagerListener_ = nullptr;
300 } else {
301 screenGroupListeners_.insert(listener);
302 }
303 return ret;
304 }
305
RegisterScreenGroupListener(sptr<IScreenGroupListener> listener)306 bool ScreenManager::RegisterScreenGroupListener(sptr<IScreenGroupListener> listener)
307 {
308 if (listener == nullptr) {
309 WLOGFE("RegisterScreenGroupListener listener is nullptr.");
310 return false;
311 }
312 return pImpl_->RegisterScreenGroupListener(listener);
313 }
314
UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener)315 bool ScreenManager::Impl::UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener)
316 {
317 std::lock_guard<std::recursive_mutex> lock(mutex_);
318 auto iter = std::find(screenGroupListeners_.begin(), screenGroupListeners_.end(), listener);
319 if (iter == screenGroupListeners_.end()) {
320 WLOGFE("could not find this listener");
321 return false;
322 }
323 bool ret = true;
324 screenGroupListeners_.erase(iter);
325 if (screenGroupListeners_.empty() && screenGroupListeners_.empty() && screenManagerListener_ != nullptr) {
326 ret = SingletonContainer::Get<ScreenManagerAdapter>().UnregisterDisplayManagerAgent(
327 screenManagerListener_,
328 DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
329 screenManagerListener_ = nullptr;
330 }
331 return ret;
332 }
333
UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener)334 bool ScreenManager::UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener)
335 {
336 if (listener == nullptr) {
337 WLOGFE("UnregisterScreenGroupListener listener is nullptr.");
338 return false;
339 }
340 return pImpl_->UnregisterScreenGroupListener(listener);
341 }
342
MakeExpand(const std::vector<ExpandOption> & options)343 ScreenId ScreenManager::MakeExpand(const std::vector<ExpandOption>& options)
344 {
345 WLOGFI("Make expand");
346 if (options.empty()) {
347 return SCREEN_ID_INVALID;
348 }
349 if (options.size() > MAX_SCREEN_SIZE) {
350 WLOGFW("Make expand failed. The options size is bigger than %{public}u.", MAX_SCREEN_SIZE);
351 return SCREEN_ID_INVALID;
352 }
353 std::vector<ScreenId> screenIds;
354 std::vector<Point> startPoints;
355 for (auto& option: options) {
356 if (std::find(screenIds.begin(), screenIds.end(), option.screenId_) != screenIds.end()) {
357 continue;
358 }
359 screenIds.emplace_back(option.screenId_);
360 startPoints.emplace_back(Point(option.startX_, option.startY_));
361 }
362 ScreenId group = SingletonContainer::Get<ScreenManagerAdapter>().MakeExpand(screenIds, startPoints);
363 if (group == SCREEN_ID_INVALID) {
364 WLOGFI("Make expand failed");
365 }
366 return group;
367 }
368
MakeMirror(ScreenId mainScreenId,std::vector<ScreenId> mirrorScreenId)369 ScreenId ScreenManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenId)
370 {
371 WLOGFI("create mirror for screen: %{public}" PRIu64"", mainScreenId);
372 if (mirrorScreenId.size() > MAX_SCREEN_SIZE) {
373 WLOGFW("Make Mirror failed. The mirrorScreenId size is bigger than %{public}u.", MAX_SCREEN_SIZE);
374 return SCREEN_ID_INVALID;
375 }
376 ScreenId group = SingletonContainer::Get<ScreenManagerAdapter>().MakeMirror(mainScreenId, mirrorScreenId);
377 if (group == SCREEN_ID_INVALID) {
378 WLOGFI("create mirror failed");
379 }
380 return group;
381 }
382
RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)383 void ScreenManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
384 {
385 if (screens.empty()) {
386 WLOGFW("RemoveVirtualScreenFromGroup failed. screens is empty.");
387 return;
388 }
389 if (screens.size() > MAX_SCREEN_SIZE) {
390 WLOGFW("RemoveVirtualScreenFromGroup failed. The screens size is bigger than %{public}u.", MAX_SCREEN_SIZE);
391 return;
392 }
393 SingletonContainer::Get<ScreenManagerAdapter>().RemoveVirtualScreenFromGroup(screens);
394 }
395
CreateVirtualScreen(VirtualScreenOption option)396 ScreenId ScreenManager::CreateVirtualScreen(VirtualScreenOption option)
397 {
398 return SingletonContainer::Get<ScreenManagerAdapter>().CreateVirtualScreen(option);
399 }
400
DestroyVirtualScreen(ScreenId screenId)401 DMError ScreenManager::DestroyVirtualScreen(ScreenId screenId)
402 {
403 return SingletonContainer::Get<ScreenManagerAdapter>().DestroyVirtualScreen(screenId);
404 }
405
SetVirtualScreenSurface(ScreenId screenId,sptr<Surface> surface)406 DMError ScreenManager::SetVirtualScreenSurface(ScreenId screenId, sptr<Surface> surface)
407 {
408 return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualScreenSurface(screenId, surface);
409 }
410
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)411 bool ScreenManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
412 {
413 WLOGFI("state:%{public}u, reason:%{public}u", state, reason);
414 return SingletonContainer::Get<ScreenManagerAdapter>().SetScreenPowerForAll(state, reason);
415 }
416
GetScreenPower(ScreenId dmsScreenId)417 ScreenPowerState ScreenManager::GetScreenPower(ScreenId dmsScreenId)
418 {
419 return SingletonContainer::Get<ScreenManagerAdapter>().GetScreenPower(dmsScreenId);
420 }
421
NotifyScreenConnect(sptr<ScreenInfo> info)422 void ScreenManager::Impl::NotifyScreenConnect(sptr<ScreenInfo> info)
423 {
424 std::lock_guard<std::recursive_mutex> lock(mutex_);
425 UpdateScreenInfoLocked(info);
426 }
427
NotifyScreenDisconnect(ScreenId screenId)428 void ScreenManager::Impl::NotifyScreenDisconnect(ScreenId screenId)
429 {
430 WLOGFI("screenId:%{public}" PRIu64".", screenId);
431 std::lock_guard<std::recursive_mutex> lock(mutex_);
432 screenMap_.erase(screenId);
433 }
434
NotifyScreenChange(const sptr<ScreenInfo> & screenInfo)435 void ScreenManager::Impl::NotifyScreenChange(const sptr<ScreenInfo>& screenInfo)
436 {
437 std::lock_guard<std::recursive_mutex> lock(mutex_);
438 UpdateScreenInfoLocked(screenInfo);
439 }
440
NotifyScreenChange(const std::vector<sptr<ScreenInfo>> & screenInfos)441 void ScreenManager::Impl::NotifyScreenChange(const std::vector<sptr<ScreenInfo>>& screenInfos)
442 {
443 std::lock_guard<std::recursive_mutex> lock(mutex_);
444 for (auto screenInfo : screenInfos) {
445 UpdateScreenInfoLocked(screenInfo);
446 }
447 }
448
UpdateScreenInfoLocked(sptr<ScreenInfo> screenInfo)449 bool ScreenManager::Impl::UpdateScreenInfoLocked(sptr<ScreenInfo> screenInfo)
450 {
451 if (screenInfo == nullptr) {
452 WLOGFE("displayInfo is null");
453 return false;
454 }
455 ScreenId screenId = screenInfo->GetScreenId();
456 WLOGFI("screenId:%{public}" PRIu64".", screenId);
457 if (screenId == SCREEN_ID_INVALID) {
458 WLOGFE("displayId is invalid.");
459 return false;
460 }
461 auto iter = screenMap_.find(screenId);
462 if (iter != screenMap_.end() && iter->second != nullptr) {
463 WLOGFI("get screen in screen map");
464 iter->second->UpdateScreenInfo(screenInfo);
465 return true;
466 }
467 sptr<Screen> screen = new Screen(screenInfo);
468 screenMap_[screenId] = screen;
469 return true;
470 }
471 } // namespace OHOS::Rosen