• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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