1 /*
2  * Copyright (c) 2024 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_lite.h"
16 #include <cinttypes>
17 #include "display_manager_adapter_lite.h"
18 #include "display_manager_agent_default.h"
19 #include "singleton_delegator.h"
20 #include "window_manager_hilog.h"
21 
22 namespace OHOS::Rosen {
23 namespace {
24     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "ScreenManagerLite"};
25 }
26 
27 /*
28  * used by powermgr
29  */
30 class ScreenManagerLite::Impl : public RefBase {
31 public:
32     Impl() = default;
33     ~Impl();
34 
35     static inline SingletonDelegator<ScreenManagerLite> delegator;
36     DMError RegisterScreenListener(sptr<IScreenListener> listener);
37     DMError UnregisterScreenListener(sptr<IScreenListener> listener);
38     DMError RegisterDisplayManagerAgent();
39     DMError UnregisterDisplayManagerAgent();
40     void OnRemoteDied();
41 
42 private:
43     void NotifyScreenConnect(sptr<ScreenInfo> info);
44     void NotifyScreenDisconnect(ScreenId);
45     void NotifyScreenChange(const sptr<ScreenInfo>& screenInfo);
46 
47     class ScreenManagerListener;
48     sptr<ScreenManagerListener> screenManagerListener_;
49     std::mutex mutex_;
50     std::set<sptr<IScreenListener>> screenListeners_;
51 };
52 
53 class ScreenManagerLite::Impl::ScreenManagerListener : public DisplayManagerAgentDefault {
54 public:
ScreenManagerListener(sptr<Impl> impl)55     explicit ScreenManagerListener(sptr<Impl> impl) : pImpl_(impl)
56     {
57     }
58 
OnScreenConnect(sptr<ScreenInfo> screenInfo)59     void OnScreenConnect(sptr<ScreenInfo> screenInfo)
60     {
61         if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) {
62             WLOGFE("OnScreenConnect, screenInfo is invalid.");
63             return;
64         }
65         if (pImpl_ == nullptr) {
66             WLOGFE("OnScreenConnect, impl is nullptr.");
67             return;
68         }
69         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
70         for (auto listener : pImpl_->screenListeners_) {
71             listener->OnConnect(screenInfo->GetScreenId());
72         }
73     };
74 
OnScreenDisconnect(ScreenId screenId)75     void OnScreenDisconnect(ScreenId screenId)
76     {
77         if (screenId == SCREEN_ID_INVALID) {
78             WLOGFE("OnScreenDisconnect, screenId is invalid.");
79             return;
80         }
81         if (pImpl_ == nullptr) {
82             WLOGFE("OnScreenDisconnect, impl is nullptr.");
83             return;
84         }
85         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
86         for (auto listener : pImpl_->screenListeners_) {
87             listener->OnDisconnect(screenId);
88         }
89     };
90 
OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)91     void OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)
92     {
93         if (screenInfo == nullptr) {
94             WLOGFE("OnScreenChange, screenInfo is null.");
95             return;
96         }
97         if (pImpl_ == nullptr) {
98             WLOGFE("OnScreenChange, impl is nullptr.");
99             return;
100         }
101         WLOGFD("OnScreenChange. event %{public}u", event);
102         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
103         for (auto listener: pImpl_->screenListeners_) {
104             listener->OnChange(screenInfo->GetScreenId());
105         }
106     };
107 private:
108     sptr<Impl> pImpl_;
109 };
110 
111 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerLite)
112 
ScreenManagerLite()113 ScreenManagerLite::ScreenManagerLite()
114 {
115     pImpl_ = new Impl();
116     WLOGFD("Create ScreenManagerLite instance");
117 }
118 
~ScreenManagerLite()119 ScreenManagerLite::~ScreenManagerLite()
120 {
121     WLOGFD("Destroy ScreenManagerLite instance");
122 }
123 
~Impl()124 ScreenManagerLite::Impl::~Impl()
125 {
126     std::lock_guard<std::mutex> lock(mutex_);
127     UnregisterDisplayManagerAgent();
128 }
129 
RegisterDisplayManagerAgent()130 DMError ScreenManagerLite::Impl::RegisterDisplayManagerAgent()
131 {
132     DMError regSucc = DMError::DM_OK;
133     if (screenManagerListener_ == nullptr) {
134         screenManagerListener_ = new ScreenManagerListener(this);
135         regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
136             screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
137         if (regSucc != DMError::DM_OK) {
138             screenManagerListener_ = nullptr;
139             WLOGFW("RegisterDisplayManagerAgent failed !");
140         }
141     }
142     return regSucc;
143 }
144 
UnregisterDisplayManagerAgent()145 DMError ScreenManagerLite::Impl::UnregisterDisplayManagerAgent()
146 {
147     DMError unRegSucc = DMError::DM_OK;
148     if (screenManagerListener_ != nullptr) {
149         unRegSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
150             screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
151         screenManagerListener_ = nullptr;
152         if (unRegSucc != DMError::DM_OK) {
153             WLOGFW("UnregisterDisplayManagerAgent failed!");
154         }
155     }
156     return unRegSucc;
157 }
158 
RegisterScreenListener(sptr<IScreenListener> listener)159 DMError ScreenManagerLite::Impl::RegisterScreenListener(sptr<IScreenListener> listener)
160 {
161     std::lock_guard<std::mutex> lock(mutex_);
162     DMError regSucc = RegisterDisplayManagerAgent();
163     if (regSucc == DMError::DM_OK) {
164         screenListeners_.insert(listener);
165     }
166     return regSucc;
167 }
168 
RegisterScreenListener(sptr<IScreenListener> listener)169 DMError ScreenManagerLite::RegisterScreenListener(sptr<IScreenListener> listener)
170 {
171     if (listener == nullptr) {
172         WLOGFE("RegisterScreenListener listener is nullptr.");
173         return DMError::DM_ERROR_NULLPTR;
174     }
175     return pImpl_->RegisterScreenListener(listener);
176 }
177 
UnregisterScreenListener(sptr<IScreenListener> listener)178 DMError ScreenManagerLite::Impl::UnregisterScreenListener(sptr<IScreenListener> listener)
179 {
180     std::lock_guard<std::mutex> lock(mutex_);
181     auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener);
182     if (iter == screenListeners_.end()) {
183         WLOGFE("could not find this listener");
184         return DMError::DM_ERROR_NULLPTR;
185     }
186     screenListeners_.erase(iter);
187     return UnregisterDisplayManagerAgent();
188 }
189 
UnregisterScreenListener(sptr<IScreenListener> listener)190 DMError ScreenManagerLite::UnregisterScreenListener(sptr<IScreenListener> listener)
191 {
192     if (listener == nullptr) {
193         WLOGFE("UnregisterScreenListener listener is nullptr.");
194         return DMError::DM_ERROR_NULLPTR;
195     }
196     return pImpl_->UnregisterScreenListener(listener);
197 }
198 
SetSpecifiedScreenPower(ScreenId screenId, ScreenPowerState state, PowerStateChangeReason reason)199 bool ScreenManagerLite::SetSpecifiedScreenPower(ScreenId screenId,
200     ScreenPowerState state, PowerStateChangeReason reason)
201 {
202     WLOGFI("screenId:%{public}" PRIu64 ", state:%{public}u, reason:%{public}u", screenId, state, reason);
203     return SingletonContainer::Get<ScreenManagerAdapterLite>().SetSpecifiedScreenPower(screenId, state, reason);
204 }
205 
SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)206 bool ScreenManagerLite::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
207 {
208     WLOGFI("state:%{public}u, reason:%{public}u", state, reason);
209     return SingletonContainer::Get<ScreenManagerAdapterLite>().SetScreenPowerForAll(state, reason);
210 }
211 
GetScreenPower(ScreenId dmsScreenId)212 ScreenPowerState ScreenManagerLite::GetScreenPower(ScreenId dmsScreenId)
213 {
214     return SingletonContainer::Get<ScreenManagerAdapterLite>().GetScreenPower(dmsScreenId);
215 }
216 
OnRemoteDied()217 void ScreenManagerLite::Impl::OnRemoteDied()
218 {
219     WLOGFD("dms is died");
220     std::lock_guard<std::mutex> lock(mutex_);
221     screenManagerListener_ = nullptr;
222 }
223 
OnRemoteDied()224 void ScreenManagerLite::OnRemoteDied()
225 {
226     pImpl_->OnRemoteDied();
227 }
228 
229 } // namespace OHOS::Rosen