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 "permission.h"
25#include "singleton_delegator.h"
26#include "window_manager_hilog.h"
27
28namespace OHOS::Rosen {
29namespace {
30constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "ScreenManager"};
31const static uint32_t MAX_SCREEN_SIZE = 32;
32}
33class ScreenManager::Impl : public RefBase {
34public:
35    Impl() = default;
36    ~Impl();
37
38    static inline SingletonDelegator<ScreenManager> delegator;
39    ScreenId CreateVirtualScreen(VirtualScreenOption option);
40    sptr<Screen> GetScreen(ScreenId screenId);
41    sptr<ScreenGroup> GetScreenGroup(ScreenId screenId);
42    DMError GetAllScreens(std::vector<sptr<Screen>>& screens);
43    DMError RegisterScreenListener(sptr<IScreenListener> listener);
44    DMError UnregisterScreenListener(sptr<IScreenListener> listener);
45    DMError RegisterScreenGroupListener(sptr<IScreenGroupListener> listener);
46    DMError UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener);
47    DMError RegisterVirtualScreenGroupListener(sptr<IVirtualScreenGroupListener> listener);
48    DMError UnregisterVirtualScreenGroupListener(sptr<IVirtualScreenGroupListener> listener);
49    DMError RegisterDisplayManagerAgent();
50    DMError UnregisterDisplayManagerAgent();
51    void OnRemoteDied();
52
53private:
54    void NotifyScreenConnect(sptr<ScreenInfo> info);
55    void NotifyScreenDisconnect(ScreenId);
56    void NotifyScreenChange(const sptr<ScreenInfo>& screenInfo);
57    void NotifyScreenChange(const std::vector<sptr<ScreenInfo>>& screenInfos);
58    bool UpdateScreenInfoLocked(sptr<ScreenInfo>);
59    std::string GetScreenInfoSrting(sptr<ScreenInfo> screenInfo);
60
61    bool isAllListenersRemoved() const;
62
63    class ScreenManagerListener;
64    sptr<ScreenManagerListener> screenManagerListener_;
65    std::map<ScreenId, sptr<Screen>> screenMap_;
66    std::map<ScreenId, sptr<ScreenGroup>> screenGroupMap_;
67    std::recursive_mutex mutex_;
68    std::set<sptr<IScreenListener>> screenListeners_;
69    std::set<sptr<IScreenGroupListener>> screenGroupListeners_;
70    std::set<sptr<IVirtualScreenGroupListener>> virtualScreenGroupListeners_;
71    sptr<IDisplayManagerAgent> virtualScreenAgent_ = nullptr;
72    std::mutex virtualScreenAgentMutex_;
73};
74
75class ScreenManager::Impl::ScreenManagerListener : public DisplayManagerAgentDefault {
76public:
77    explicit ScreenManagerListener(sptr<Impl> impl) : pImpl_(impl)
78    {
79    }
80
81    void OnScreenConnect(sptr<ScreenInfo> screenInfo)
82    {
83        if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) {
84            WLOGFE("OnScreenConnect, screenInfo is invalid.");
85            return;
86        }
87        if (pImpl_ == nullptr) {
88            WLOGFE("OnScreenConnect, impl is nullptr.");
89            return;
90        }
91        pImpl_->NotifyScreenConnect(screenInfo);
92        std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
93        for (auto listener : pImpl_->screenListeners_) {
94            listener->OnConnect(screenInfo->GetScreenId());
95        }
96    };
97
98    void OnScreenDisconnect(ScreenId screenId)
99    {
100        if (screenId == SCREEN_ID_INVALID) {
101            WLOGFE("OnScreenDisconnect, screenId is invalid.");
102            return;
103        }
104        if (pImpl_ == nullptr) {
105            WLOGFE("OnScreenDisconnect, impl is nullptr.");
106            return;
107        }
108        pImpl_->NotifyScreenDisconnect(screenId);
109        std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
110        for (auto listener : pImpl_->screenListeners_) {
111            listener->OnDisconnect(screenId);
112        }
113    };
114
115    void OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)
116    {
117        if (screenInfo == nullptr) {
118            WLOGFE("OnScreenChange, screenInfo is null.");
119            return;
120        }
121        if (pImpl_ == nullptr) {
122            WLOGFE("OnScreenChange, impl is nullptr.");
123            return;
124        }
125        WLOGFD("OnScreenChange. event %{public}u", event);
126        pImpl_->NotifyScreenChange(screenInfo);
127        std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
128        for (auto listener: pImpl_->screenListeners_) {
129            listener->OnChange(screenInfo->GetScreenId());
130        }
131    };
132
133    void OnScreenGroupChange(const std::string& trigger, const std::vector<sptr<ScreenInfo>>& screenInfos,
134        ScreenGroupChangeEvent groupEvent)
135    {
136        if (screenInfos.empty()) {
137            WLOGFE("screenInfos is empty.");
138            return;
139        }
140        if (pImpl_ == nullptr) {
141            WLOGFE("impl is nullptr.");
142            return;
143        }
144        WLOGFD("trigger %{public}s, event %{public}u", trigger.c_str(), groupEvent);
145        pImpl_->NotifyScreenChange(screenInfos);
146        std::vector<ScreenId> screenIds;
147        for (auto screenInfo : screenInfos) {
148            if (screenInfo->GetScreenId() != SCREEN_ID_INVALID) {
149                screenIds.push_back(screenInfo->GetScreenId());
150            }
151        }
152        std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
153        for (auto listener: pImpl_->screenGroupListeners_) {
154            listener->OnChange(screenIds, groupEvent);
155        }
156        NotifyVirtualScreenGroupChanged(screenInfos[0], trigger, screenIds, groupEvent);
157    };
158private:
159    void NotifyVirtualScreenGroupChanged(sptr<ScreenInfo> screenInfo,
160        const std::string trigger, std::vector<ScreenId>& ids, ScreenGroupChangeEvent groupEvent)
161    {
162        if (screenInfo == nullptr) {
163            WLOGFE("screenInfo is nullptr");
164            return;
165        }
166        // check for invalid scene
167        if (pImpl_->virtualScreenGroupListeners_.size() <= 0) {
168            WLOGFW("no virtual screen group listeners");
169            return;
170        }
171        if (screenInfo->GetType() != ScreenType::VIRTUAL) {
172            WLOGFW("not virtual screen type: %{public}u", screenInfo->GetType());
173            return;
174        }
175
176        // get the parent of screen
177        ScreenId parent = groupEvent == ScreenGroupChangeEvent::ADD_TO_GROUP ?
178            screenInfo->GetParentId() : screenInfo->GetLastParentId();
179        WLOGFD("parentId=[%{public}llu], lastParentId=[%{public}llu]", (unsigned long long)screenInfo->GetParentId(),
180            (unsigned long long)screenInfo->GetLastParentId());
181        if (parent == INVALID_SCREEN_ID) {
182            WLOGFE("parentId is invalid");
183            return;
184        }
185        auto screenGroup = pImpl_->GetScreenGroup(parent);
186        if (screenGroup == nullptr) {
187            WLOGFE("screenGroup is null");
188            return;
189        }
190
191        // notify mirror
192        ScreenCombination comb = screenGroup->GetCombination();
193        WLOGFD("comb %{public}u", comb);
194        IVirtualScreenGroupListener::ChangeInfo changeInfo = {groupEvent, trigger, ids};
195        for (auto listener: pImpl_->virtualScreenGroupListeners_) {
196            if (comb == ScreenCombination::SCREEN_MIRROR) {
197                listener->OnMirrorChange(changeInfo);
198            }
199        }
200    }
201    sptr<Impl> pImpl_;
202};
203
204WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManager)
205
206ScreenManager::ScreenManager()
207{
208    pImpl_ = new Impl();
209    WLOGFD("Create screenmanager instance");
210}
211
212ScreenManager::~ScreenManager()
213{
214    WLOGFI("Destroy screenmanager instance");
215}
216
217ScreenManager::Impl::~Impl()
218{
219    std::lock_guard<std::recursive_mutex> lock(mutex_);
220    UnregisterDisplayManagerAgent();
221}
222
223sptr<Screen> ScreenManager::Impl::GetScreen(ScreenId screenId)
224{
225    auto screenInfo = SingletonContainer::Get<ScreenManagerAdapter>().GetScreenInfo(screenId);
226    std::lock_guard<std::recursive_mutex> lock(mutex_);
227    if (!UpdateScreenInfoLocked(screenInfo)) {
228        screenMap_.erase(screenId);
229        return nullptr;
230    }
231    return screenMap_[screenId];
232}
233
234sptr<Screen> ScreenManager::GetScreenById(ScreenId screenId)
235{
236    return pImpl_->GetScreen(screenId);
237}
238
239sptr<ScreenGroup> ScreenManager::Impl::GetScreenGroup(ScreenId screenId)
240{
241    auto screenGroupInfo = SingletonContainer::Get<ScreenManagerAdapter>().GetScreenGroupInfoById(screenId);
242    std::lock_guard<std::recursive_mutex> lock(mutex_);
243    if (screenGroupInfo == nullptr) {
244        WLOGFE("screenGroupInfo is null");
245        screenGroupMap_.erase(screenId);
246        return nullptr;
247    }
248    auto iter = screenGroupMap_.find(screenId);
249    if (iter != screenGroupMap_.end() && iter->second != nullptr) {
250        iter->second->UpdateScreenGroupInfo(screenGroupInfo);
251        return iter->second;
252    }
253    sptr<ScreenGroup> screenGroup = new ScreenGroup(screenGroupInfo);
254    screenGroupMap_[screenId] = screenGroup;
255    return screenGroup;
256}
257
258sptr<ScreenGroup> ScreenManager::GetScreenGroup(ScreenId screenId)
259{
260    return pImpl_->GetScreenGroup(screenId);
261}
262
263DMError ScreenManager::Impl::GetAllScreens(std::vector<sptr<Screen>>& screens)
264{
265    std::vector<sptr<ScreenInfo>> screenInfos;
266    DMError ret  = SingletonContainer::Get<ScreenManagerAdapter>().GetAllScreenInfos(screenInfos);
267    std::lock_guard<std::recursive_mutex> lock(mutex_);
268    for (auto info: screenInfos) {
269        if (UpdateScreenInfoLocked(info)) {
270            screens.emplace_back(screenMap_[info->GetScreenId()]);
271        }
272    }
273    screenMap_.clear();
274    for (auto screen: screens) {
275        screenMap_.insert(std::make_pair(screen->GetId(), screen));
276    }
277    return ret;
278}
279
280DMError ScreenManager::GetAllScreens(std::vector<sptr<Screen>>& screens)
281{
282    return pImpl_->GetAllScreens(screens);
283}
284
285DMError ScreenManager::Impl::RegisterScreenListener(sptr<IScreenListener> listener)
286{
287    std::lock_guard<std::recursive_mutex> lock(mutex_);
288    DMError regSucc = RegisterDisplayManagerAgent();
289    if (regSucc == DMError::DM_OK) {
290        screenListeners_.insert(listener);
291    }
292    return regSucc;
293}
294
295DMError ScreenManager::RegisterScreenListener(sptr<IScreenListener> listener)
296{
297    if (listener == nullptr) {
298        WLOGFE("RegisterScreenListener listener is nullptr.");
299        return DMError::DM_ERROR_NULLPTR;
300    }
301    return pImpl_->RegisterScreenListener(listener);
302}
303
304DMError ScreenManager::Impl::UnregisterScreenListener(sptr<IScreenListener> listener)
305{
306    std::lock_guard<std::recursive_mutex> lock(mutex_);
307    auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener);
308    if (iter == screenListeners_.end()) {
309        WLOGFE("could not find this listener");
310        return DMError::DM_ERROR_NULLPTR;
311    }
312    screenListeners_.erase(iter);
313    return isAllListenersRemoved() ? UnregisterDisplayManagerAgent() : DMError::DM_OK;
314}
315
316DMError ScreenManager::UnregisterScreenListener(sptr<IScreenListener> listener)
317{
318    if (listener == nullptr) {
319        WLOGFE("UnregisterScreenListener listener is nullptr.");
320        return DMError::DM_ERROR_NULLPTR;
321    }
322    return pImpl_->UnregisterScreenListener(listener);
323}
324
325DMError ScreenManager::Impl::RegisterScreenGroupListener(sptr<IScreenGroupListener> listener)
326{
327    std::lock_guard<std::recursive_mutex> lock(mutex_);
328    DMError regSucc = RegisterDisplayManagerAgent();
329    if (regSucc == DMError::DM_OK) {
330        screenGroupListeners_.insert(listener);
331    }
332    return regSucc;
333}
334
335DMError ScreenManager::RegisterScreenGroupListener(sptr<IScreenGroupListener> listener)
336{
337    if (listener == nullptr) {
338        WLOGFE("RegisterScreenGroupListener listener is nullptr.");
339        return DMError::DM_ERROR_NULLPTR;
340    }
341    return pImpl_->RegisterScreenGroupListener(listener);
342}
343
344DMError ScreenManager::Impl::UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener)
345{
346    std::lock_guard<std::recursive_mutex> lock(mutex_);
347    auto iter = std::find(screenGroupListeners_.begin(), screenGroupListeners_.end(), listener);
348    if (iter == screenGroupListeners_.end()) {
349        WLOGFE("could not find this listener");
350        return DMError::DM_ERROR_NULLPTR;
351    }
352    screenGroupListeners_.erase(iter);
353    return isAllListenersRemoved() ? UnregisterDisplayManagerAgent() : DMError::DM_OK;
354}
355
356DMError ScreenManager::UnregisterScreenGroupListener(sptr<IScreenGroupListener> listener)
357{
358    if (listener == nullptr) {
359        WLOGFE("UnregisterScreenGroupListener listener is nullptr.");
360        return DMError::DM_ERROR_NULLPTR;
361    }
362    return pImpl_->UnregisterScreenGroupListener(listener);
363}
364
365DMError ScreenManager::Impl::RegisterVirtualScreenGroupListener(sptr<IVirtualScreenGroupListener> listener)
366{
367    std::lock_guard<std::recursive_mutex> lock(mutex_);
368    DMError regSucc = RegisterDisplayManagerAgent();
369    if (regSucc == DMError::DM_OK) {
370        virtualScreenGroupListeners_.insert(listener);
371    }
372    return regSucc;
373}
374
375DMError ScreenManager::RegisterVirtualScreenGroupListener(sptr<IVirtualScreenGroupListener> listener)
376{
377    if (listener == nullptr) {
378        WLOGFE("RegisterVirtualScreenGroupListener listener is nullptr.");
379        return DMError::DM_ERROR_NULLPTR;
380    }
381    return pImpl_->RegisterVirtualScreenGroupListener(listener);
382}
383
384DMError ScreenManager::Impl::UnregisterVirtualScreenGroupListener(sptr<IVirtualScreenGroupListener> listener)
385{
386    std::lock_guard<std::recursive_mutex> lock(mutex_);
387    auto iter = std::find(virtualScreenGroupListeners_.begin(), virtualScreenGroupListeners_.end(), listener);
388    if (iter == virtualScreenGroupListeners_.end()) {
389        WLOGFE("could not find this listener");
390        return DMError::DM_ERROR_NULLPTR;
391    }
392    virtualScreenGroupListeners_.erase(iter);
393    return isAllListenersRemoved() ? UnregisterDisplayManagerAgent() : DMError::DM_OK;
394}
395
396DMError ScreenManager::UnregisterVirtualScreenGroupListener(sptr<IVirtualScreenGroupListener> listener)
397{
398    if (listener == nullptr) {
399        WLOGFE("UnregisterVirtualScreenGroupListener listener is nullptr.");
400        return DMError::DM_ERROR_NULLPTR;
401    }
402    return pImpl_->UnregisterVirtualScreenGroupListener(listener);
403}
404
405DMError ScreenManager::Impl::RegisterDisplayManagerAgent()
406{
407    DMError regSucc = DMError::DM_OK;
408    if (screenManagerListener_ == nullptr) {
409        screenManagerListener_ = new ScreenManagerListener(this);
410        regSucc = SingletonContainer::Get<ScreenManagerAdapter>().RegisterDisplayManagerAgent(
411            screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
412        if (regSucc != DMError::DM_OK) {
413            screenManagerListener_ = nullptr;
414            WLOGFW("RegisterDisplayManagerAgent failed !");
415        }
416    }
417    return regSucc;
418}
419
420DMError ScreenManager::Impl::UnregisterDisplayManagerAgent()
421{
422    DMError unRegSucc = DMError::DM_OK;
423    if (screenManagerListener_ != nullptr) {
424        unRegSucc = SingletonContainer::Get<ScreenManagerAdapter>().UnregisterDisplayManagerAgent(
425            screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
426        screenManagerListener_ = nullptr;
427        if (unRegSucc != DMError::DM_OK) {
428            WLOGFW("UnregisterDisplayManagerAgent failed!");
429        }
430    }
431    return unRegSucc;
432}
433
434DMError ScreenManager::MakeExpand(const std::vector<ExpandOption>& options, ScreenId& screenGroupId)
435{
436    WLOGFD("Make expand");
437    if (options.empty()) {
438        return DMError::DM_ERROR_INVALID_PARAM;
439    }
440    if (options.size() > MAX_SCREEN_SIZE) {
441        WLOGFW("Make expand failed. The options size is bigger than %{public}u.", MAX_SCREEN_SIZE);
442        return DMError::DM_ERROR_INVALID_PARAM;
443    }
444    std::vector<ScreenId> screenIds;
445    std::vector<Point> startPoints;
446    for (auto& option: options) {
447        if (std::find(screenIds.begin(), screenIds.end(), option.screenId_) != screenIds.end()) {
448            continue;
449        }
450        screenIds.emplace_back(option.screenId_);
451        startPoints.emplace_back(Point(option.startX_, option.startY_));
452    }
453    DMError ret = SingletonContainer::Get<ScreenManagerAdapter>().MakeExpand(screenIds, startPoints, screenGroupId);
454    if (screenGroupId == SCREEN_ID_INVALID) {
455        WLOGFE("Make expand failed");
456    }
457    return ret;
458}
459
460DMError ScreenManager::MakeUniqueScreen(const std::vector<ScreenId>& screenIds)
461{
462    WLOGFD("start Make UniqueScreen");
463    if (screenIds.empty()) {
464        WLOGFE("screenIds is null");
465        return DMError::DM_ERROR_INVALID_PARAM;
466    }
467    if (screenIds.size() > MAX_SCREEN_SIZE) {
468        WLOGFW("Make UniqueScreen failed. The screenIds size is bigger than %{public}u.", MAX_SCREEN_SIZE);
469        return DMError::DM_ERROR_INVALID_PARAM;
470    }
471    DMError ret = SingletonContainer::Get<ScreenManagerAdapter>().MakeUniqueScreen(screenIds);
472    return ret;
473}
474
475DMError ScreenManager::MakeMirror(ScreenId mainScreenId, std::vector<ScreenId> mirrorScreenId, ScreenId& screenGroupId)
476{
477    WLOGFI("Make mirror for screen: %{public}" PRIu64"", mainScreenId);
478    if (mirrorScreenId.size() > MAX_SCREEN_SIZE) {
479        WLOGFW("Make Mirror failed. The mirrorScreenId size is bigger than %{public}u.", MAX_SCREEN_SIZE);
480        return DMError::DM_ERROR_INVALID_PARAM;
481    }
482    DMError ret = SingletonContainer::Get<ScreenManagerAdapter>().MakeMirror(mainScreenId, mirrorScreenId,
483                                                                             screenGroupId);
484    if (screenGroupId == SCREEN_ID_INVALID) {
485        WLOGFE("create mirror failed");
486    }
487    return ret;
488}
489
490DMError ScreenManager::SetMultiScreenMode(ScreenId mainScreenId, ScreenId secondaryScreenId,
491    MultiScreenMode screenMode)
492{
493    WLOGFI("mainScreenId:%{public}" PRIu64",secondaryScreenId:%{public}" PRIu64",screenMode:%{public}u",
494        mainScreenId, secondaryScreenId, screenMode);
495    DMError ret = SingletonContainer::Get<ScreenManagerAdapter>().SetMultiScreenMode(mainScreenId,
496        secondaryScreenId, screenMode);
497    return ret;
498}
499
500DMError ScreenManager::SetMultiScreenRelativePosition(MultiScreenPositionOptions mainScreenOptions,
501    MultiScreenPositionOptions secondScreenOption)
502{
503    WLOGFI("mId:%{public}" PRIu64", X:%{public}u, Y:%{public}u,sId:%{public}" PRIu64", X:%{public}u, Y:%{public}u",
504        mainScreenOptions.screenId_, mainScreenOptions.startX_, mainScreenOptions.startY_,
505        secondScreenOption.screenId_, secondScreenOption.startX_, secondScreenOption.startY_);
506    DMError ret = SingletonContainer::Get<ScreenManagerAdapter>().SetMultiScreenRelativePosition(mainScreenOptions,
507        secondScreenOption);
508    return ret;
509}
510
511DMError ScreenManager::StopExpand(const std::vector<ScreenId>& expandScreenIds)
512{
513    WLOGFD("Stop expand");
514    if (expandScreenIds.empty()) {
515        return DMError::DM_OK;
516    }
517    return SingletonContainer::Get<ScreenManagerAdapter>().StopExpand(expandScreenIds);
518}
519
520DMError ScreenManager::StopMirror(const std::vector<ScreenId>& mirrorScreenIds)
521{
522    WLOGFD("Stop mirror");
523    if (mirrorScreenIds.empty()) {
524        return DMError::DM_OK;
525    }
526    return SingletonContainer::Get<ScreenManagerAdapter>().StopMirror(mirrorScreenIds);
527}
528
529DMError ScreenManager::DisableMirror(bool disableOrNot)
530{
531    WLOGFI("Disable mirror %{public}d", disableOrNot);
532    return SingletonContainer::Get<ScreenManagerAdapter>().DisableMirror(disableOrNot);
533}
534
535DMError ScreenManager::RemoveVirtualScreenFromGroup(std::vector<ScreenId> screens)
536{
537    WLOGFI("screens.size=%{public}llu", (unsigned long long)screens.size());
538    if (screens.empty()) {
539        WLOGFW("RemoveVirtualScreenFromGroup failed. screens is empty.");
540        return DMError::DM_ERROR_INVALID_PARAM;
541    }
542    if (screens.size() > MAX_SCREEN_SIZE) {
543        WLOGFW("RemoveVirtualScreenFromGroup failed. The screens size is bigger than %{public}u.", MAX_SCREEN_SIZE);
544        return DMError::DM_ERROR_INVALID_PARAM;
545    }
546    SingletonContainer::Get<ScreenManagerAdapter>().RemoveVirtualScreenFromGroup(screens);
547    return DMError::DM_OK;
548}
549
550ScreenId ScreenManager::CreateVirtualScreen(VirtualScreenOption option)
551{
552    return pImpl_->CreateVirtualScreen(option);
553}
554
555ScreenId ScreenManager::Impl::CreateVirtualScreen(VirtualScreenOption option)
556{
557    //  After the process creating the virtual screen is killed, DMS needs to delete the virtual screen
558    std::lock_guard<std::mutex> agentLock(virtualScreenAgentMutex_);
559    if (virtualScreenAgent_ == nullptr) {
560        virtualScreenAgent_ = new DisplayManagerAgentDefault();
561    }
562    return SingletonContainer::Get<ScreenManagerAdapter>().CreateVirtualScreen(option, virtualScreenAgent_);
563}
564
565DMError ScreenManager::DestroyVirtualScreen(ScreenId screenId)
566{
567    return SingletonContainer::Get<ScreenManagerAdapter>().DestroyVirtualScreen(screenId);
568}
569
570DMError ScreenManager::SetVirtualScreenSurface(ScreenId screenId, sptr<Surface> surface)
571{
572    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualScreenSurface(screenId, surface);
573}
574
575DMError ScreenManager::ResizeVirtualScreen(ScreenId screenId, uint32_t width, uint32_t height)
576{
577    return SingletonContainer::Get<ScreenManagerAdapter>().ResizeVirtualScreen(screenId, width, height);
578}
579
580DMError ScreenManager::SetVirtualMirrorScreenCanvasRotation(ScreenId screenId, bool rotation)
581{
582    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualMirrorScreenCanvasRotation(screenId, rotation);
583}
584
585DMError ScreenManager::SetVirtualMirrorScreenScaleMode(ScreenId screenId, ScreenScaleMode scaleMode)
586{
587    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualMirrorScreenScaleMode(screenId, scaleMode);
588}
589
590VirtualScreenFlag ScreenManager::GetVirtualScreenFlag(ScreenId screenId)
591{
592    return SingletonContainer::Get<ScreenManagerAdapter>().GetVirtualScreenFlag(screenId);
593}
594
595DMError ScreenManager::SetVirtualScreenFlag(ScreenId screenId, VirtualScreenFlag screenFlag)
596{
597    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualScreenFlag(screenId, screenFlag);
598}
599
600DMError ScreenManager::SetVirtualScreenRefreshRate(ScreenId screenId, uint32_t refreshInterval)
601{
602    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualScreenRefreshRate(screenId, refreshInterval);
603}
604
605bool ScreenManager::SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state, PowerStateChangeReason reason)
606{
607    WLOGFI("screenId:%{public}" PRIu64 ", state:%{public}u, reason:%{public}u", screenId, state, reason);
608    return SingletonContainer::Get<ScreenManagerAdapter>().SetSpecifiedScreenPower(screenId, state, reason);
609}
610
611bool ScreenManager::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
612{
613    WLOGFI("state:%{public}u, reason:%{public}u", state, reason);
614    return SingletonContainer::Get<ScreenManagerAdapter>().SetScreenPowerForAll(state, reason);
615}
616
617ScreenPowerState ScreenManager::GetScreenPower(ScreenId dmsScreenId)
618{
619    return SingletonContainer::Get<ScreenManagerAdapter>().GetScreenPower(dmsScreenId);
620}
621
622DMError ScreenManager::SetScreenRotationLocked(bool isLocked)
623{
624    return SingletonContainer::Get<ScreenManagerAdapter>().SetScreenRotationLocked(isLocked);
625}
626
627DMError ScreenManager::SetScreenRotationLockedFromJs(bool isLocked)
628{
629    return SingletonContainer::Get<ScreenManagerAdapter>().SetScreenRotationLockedFromJs(isLocked);
630}
631
632DMError ScreenManager::IsScreenRotationLocked(bool& isLocked)
633{
634    return SingletonContainer::Get<ScreenManagerAdapter>().IsScreenRotationLocked(isLocked);
635}
636
637void ScreenManager::Impl::NotifyScreenConnect(sptr<ScreenInfo> info)
638{
639    std::lock_guard<std::recursive_mutex> lock(mutex_);
640    UpdateScreenInfoLocked(info);
641}
642
643void ScreenManager::Impl::NotifyScreenDisconnect(ScreenId screenId)
644{
645    WLOGFI("screenId:%{public}" PRIu64".", screenId);
646    std::lock_guard<std::recursive_mutex> lock(mutex_);
647    screenMap_.erase(screenId);
648}
649
650void ScreenManager::Impl::NotifyScreenChange(const sptr<ScreenInfo>& screenInfo)
651{
652    std::lock_guard<std::recursive_mutex> lock(mutex_);
653    UpdateScreenInfoLocked(screenInfo);
654}
655
656void ScreenManager::Impl::NotifyScreenChange(const std::vector<sptr<ScreenInfo>>& screenInfos)
657{
658    std::lock_guard<std::recursive_mutex> lock(mutex_);
659    for (auto screenInfo : screenInfos) {
660        UpdateScreenInfoLocked(screenInfo);
661    }
662}
663
664bool ScreenManager::Impl::UpdateScreenInfoLocked(sptr<ScreenInfo> screenInfo)
665{
666    if (screenInfo == nullptr) {
667        WLOGFE("displayInfo is null");
668        return false;
669    }
670    ScreenId screenId = screenInfo->GetScreenId();
671    WLOGFD("screenId:%{public}" PRIu64".", screenId);
672    if (screenId == SCREEN_ID_INVALID) {
673        WLOGFE("displayId is invalid.");
674        return false;
675    }
676    auto iter = screenMap_.find(screenId);
677    if (iter != screenMap_.end() && iter->second != nullptr) {
678        WLOGFD("Screen Info Updated: %{public}s",
679            GetScreenInfoSrting(screenInfo).c_str());
680        iter->second->UpdateScreenInfo(screenInfo);
681        return true;
682    }
683    sptr<Screen> screen = new Screen(screenInfo);
684    screenMap_[screenId] = screen;
685    return true;
686}
687
688std::string ScreenManager::Impl::GetScreenInfoSrting(sptr<ScreenInfo> screenInfo)
689{
690    if (screenInfo == nullptr) {
691        WLOGFE("screenInfo nullptr.");
692        return "";
693    }
694    std::ostringstream oss;
695    oss <<  "Screen ID: " << screenInfo->GetScreenId() << ", ";
696    oss <<  "Name: " << screenInfo->GetName() << ", ";
697    oss <<  "VirtualWidth: " << screenInfo->GetVirtualWidth() << ", ";
698    oss <<  "VirtualHeight: " << screenInfo->GetVirtualHeight() << ", ";
699    oss <<  "VirtualPixelRatio: " << screenInfo->GetVirtualPixelRatio() << ", ";
700    oss <<  "Rotation: " << static_cast<int32_t>(screenInfo->GetRotation());
701    return oss.str();
702}
703
704bool ScreenManager::Impl::isAllListenersRemoved() const
705{
706    return screenListeners_.empty() && screenGroupListeners_.empty() && virtualScreenGroupListeners_.empty();
707}
708
709void ScreenManager::Impl::OnRemoteDied()
710{
711    WLOGFD("dms is died");
712    {
713        std::lock_guard<std::mutex> agentLock(virtualScreenAgentMutex_);
714        virtualScreenAgent_ = nullptr;
715    }
716
717    std::lock_guard<std::recursive_mutex> lock(mutex_);
718    screenManagerListener_ = nullptr;
719}
720
721void ScreenManager::OnRemoteDied()
722{
723    pImpl_->OnRemoteDied();
724}
725
726bool ScreenManager::SetVirtualScreenStatus(ScreenId screenId, VirtualScreenStatus screenStatus)
727{
728    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualScreenStatus(screenId, screenStatus);
729}
730
731DMError ScreenManager::SetVirtualScreenMaxRefreshRate(ScreenId id, uint32_t refreshRate,
732    uint32_t& actualRefreshRate)
733{
734    return SingletonContainer::Get<ScreenManagerAdapter>().SetVirtualScreenMaxRefreshRate(id,
735        refreshRate, actualRefreshRate);
736}
737} // namespace OHOS::Rosen
738