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     DMError RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener);
41     DMError UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener);
42     DMError RegisterScreenModeChangeManagerAgent();
43     DMError UnregisterScreenModeChangeManagerAgent();
44     void OnRemoteDied();
45 
46 private:
47     void NotifyScreenConnect(sptr<ScreenInfo> info);
48     void NotifyScreenDisconnect(ScreenId);
49     void NotifyScreenChange(const sptr<ScreenInfo>& screenInfo);
50 
51     class ScreenManagerListener;
52     sptr<ScreenManagerListener> screenManagerListener_;
53     std::mutex mutex_;
54     std::set<sptr<IScreenListener>> screenListeners_;
55 
56     class ScreenManagerScreenModeChangeAgent;
57     std::set<sptr<IScreenModeChangeListener>> screenModeChangeListeners_;
58     sptr<ScreenManagerScreenModeChangeAgent> screenModeChangeListenerAgent_;
59 };
60 
61 class ScreenManagerLite::Impl::ScreenManagerListener : public DisplayManagerAgentDefault {
62 public:
ScreenManagerListener(sptr<Impl> impl)63     explicit ScreenManagerListener(sptr<Impl> impl) : pImpl_(impl)
64     {
65     }
66 
OnScreenConnect(sptr<ScreenInfo> screenInfo)67     void OnScreenConnect(sptr<ScreenInfo> screenInfo)
68     {
69         if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) {
70             WLOGFE("OnScreenConnect, screenInfo is invalid.");
71             return;
72         }
73         if (pImpl_ == nullptr) {
74             WLOGFE("OnScreenConnect, impl is nullptr.");
75             return;
76         }
77         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
78         for (auto listener : pImpl_->screenListeners_) {
79             listener->OnConnect(screenInfo->GetScreenId());
80         }
81     };
82 
OnScreenDisconnect(ScreenId screenId)83     void OnScreenDisconnect(ScreenId screenId)
84     {
85         if (screenId == SCREEN_ID_INVALID) {
86             WLOGFE("OnScreenDisconnect, screenId is invalid.");
87             return;
88         }
89         if (pImpl_ == nullptr) {
90             WLOGFE("OnScreenDisconnect, impl is nullptr.");
91             return;
92         }
93         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
94         for (auto listener : pImpl_->screenListeners_) {
95             listener->OnDisconnect(screenId);
96         }
97     };
98 
OnScreenChange(const sptr<ScreenInfo> & screenInfo,ScreenChangeEvent event)99     void OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)
100     {
101         if (screenInfo == nullptr) {
102             WLOGFE("OnScreenChange, screenInfo is null.");
103             return;
104         }
105         if (pImpl_ == nullptr) {
106             WLOGFE("OnScreenChange, impl is nullptr.");
107             return;
108         }
109         WLOGFD("OnScreenChange. event %{public}u", event);
110         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
111         for (auto listener: pImpl_->screenListeners_) {
112             listener->OnChange(screenInfo->GetScreenId());
113         }
114     };
115 private:
116     sptr<Impl> pImpl_;
117 };
118 
119 class ScreenManagerLite::Impl::ScreenManagerScreenModeChangeAgent : public DisplayManagerAgentDefault {
120 public:
ScreenManagerScreenModeChangeAgent(sptr<Impl> impl)121     explicit ScreenManagerScreenModeChangeAgent(sptr<Impl> impl) : pImpl_(impl)
122     {
123     }
124     ~ScreenManagerScreenModeChangeAgent() = default;
125 
NotifyScreenModeChange(const std::vector<sptr<ScreenInfo>> & screenInfos)126     virtual void NotifyScreenModeChange(const std::vector<sptr<ScreenInfo>>& screenInfos) override
127     {
128         std::lock_guard<std::mutex> lock(pImpl_->mutex_);
129         for (auto listener: pImpl_->screenModeChangeListeners_) {
130             listener->NotifyScreenModeChange(screenInfos);
131         }
132     }
133 private:
134     sptr<Impl> pImpl_;
135 };
136 
WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerLite)137 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerLite)
138 
139 ScreenManagerLite::ScreenManagerLite()
140 {
141     pImpl_ = new Impl();
142     WLOGFD("Create ScreenManagerLite instance");
143 }
144 
~ScreenManagerLite()145 ScreenManagerLite::~ScreenManagerLite()
146 {
147     WLOGFD("Destroy ScreenManagerLite instance");
148 }
149 
~Impl()150 ScreenManagerLite::Impl::~Impl()
151 {
152     std::lock_guard<std::mutex> lock(mutex_);
153     UnregisterDisplayManagerAgent();
154 }
155 
RegisterDisplayManagerAgent()156 DMError ScreenManagerLite::Impl::RegisterDisplayManagerAgent()
157 {
158     DMError regSucc = DMError::DM_OK;
159     if (screenManagerListener_ == nullptr) {
160         screenManagerListener_ = new ScreenManagerListener(this);
161         regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
162             screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
163         if (regSucc != DMError::DM_OK) {
164             screenManagerListener_ = nullptr;
165             WLOGFW("RegisterDisplayManagerAgent failed !");
166         }
167     }
168     return regSucc;
169 }
170 
UnregisterDisplayManagerAgent()171 DMError ScreenManagerLite::Impl::UnregisterDisplayManagerAgent()
172 {
173     DMError unRegSucc = DMError::DM_OK;
174     if (screenManagerListener_ != nullptr) {
175         unRegSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
176             screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
177         screenManagerListener_ = nullptr;
178         if (unRegSucc != DMError::DM_OK) {
179             WLOGFW("UnregisterDisplayManagerAgent failed!");
180         }
181     }
182     return unRegSucc;
183 }
184 
RegisterScreenListener(sptr<IScreenListener> listener)185 DMError ScreenManagerLite::Impl::RegisterScreenListener(sptr<IScreenListener> listener)
186 {
187     std::lock_guard<std::mutex> lock(mutex_);
188     DMError regSucc = RegisterDisplayManagerAgent();
189     if (regSucc == DMError::DM_OK) {
190         screenListeners_.insert(listener);
191     }
192     return regSucc;
193 }
194 
RegisterScreenListener(sptr<IScreenListener> listener)195 DMError ScreenManagerLite::RegisterScreenListener(sptr<IScreenListener> listener)
196 {
197     if (listener == nullptr) {
198         WLOGFE("RegisterScreenListener listener is nullptr.");
199         return DMError::DM_ERROR_NULLPTR;
200     }
201     return pImpl_->RegisterScreenListener(listener);
202 }
203 
UnregisterScreenListener(sptr<IScreenListener> listener)204 DMError ScreenManagerLite::Impl::UnregisterScreenListener(sptr<IScreenListener> listener)
205 {
206     std::lock_guard<std::mutex> lock(mutex_);
207     auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener);
208     if (iter == screenListeners_.end()) {
209         WLOGFE("could not find this listener");
210         return DMError::DM_ERROR_NULLPTR;
211     }
212     screenListeners_.erase(iter);
213     return UnregisterDisplayManagerAgent();
214 }
215 
UnregisterScreenListener(sptr<IScreenListener> listener)216 DMError ScreenManagerLite::UnregisterScreenListener(sptr<IScreenListener> listener)
217 {
218     if (listener == nullptr) {
219         WLOGFE("UnregisterScreenListener listener is nullptr.");
220         return DMError::DM_ERROR_NULLPTR;
221     }
222     return pImpl_->UnregisterScreenListener(listener);
223 }
224 
RegisterScreenModeChangeManagerAgent()225 DMError ScreenManagerLite::Impl::RegisterScreenModeChangeManagerAgent()
226 {
227     DMError regSucc = DMError::DM_OK;
228     if (screenModeChangeListenerAgent_ == nullptr) {
229         screenModeChangeListenerAgent_ = new ScreenManagerScreenModeChangeAgent(this);
230         regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
231             screenModeChangeListenerAgent_, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
232         if (regSucc != DMError::DM_OK) {
233             screenModeChangeListenerAgent_ = nullptr;
234             WLOGFW("RegisterDisplayManagerAgent failed !");
235         }
236     }
237     return regSucc;
238 }
239 
UnregisterScreenModeChangeManagerAgent()240 DMError ScreenManagerLite::Impl::UnregisterScreenModeChangeManagerAgent()
241 {
242     DMError unRegSucc = DMError::DM_OK;
243     if (screenModeChangeListenerAgent_ != nullptr) {
244         unRegSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
245             screenModeChangeListenerAgent_, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
246         screenModeChangeListenerAgent_ = nullptr;
247         if (unRegSucc != DMError::DM_OK) {
248             WLOGFW("UnregisterDisplayManagerAgent failed!");
249         }
250     }
251     return unRegSucc;
252 }
253 
RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)254 DMError ScreenManagerLite::Impl::RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
255 {
256     std::lock_guard<std::mutex> lock(mutex_);
257     DMError regSucc = RegisterScreenModeChangeManagerAgent();
258     if (regSucc == DMError::DM_OK) {
259         screenModeChangeListeners_.insert(listener);
260     }
261     return regSucc;
262 }
263 
RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)264 DMError ScreenManagerLite::RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
265 {
266     if (listener == nullptr) {
267         WLOGFE("RegisterScreenListener listener is nullptr.");
268         return DMError::DM_ERROR_NULLPTR;
269     }
270     return pImpl_->RegisterScreenModeChangeListener(listener);
271 }
272 
UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)273 DMError ScreenManagerLite::Impl::UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
274 {
275     std::lock_guard<std::mutex> lock(mutex_);
276     auto iter = std::find(screenModeChangeListeners_.begin(), screenModeChangeListeners_.end(), listener);
277     if (iter == screenModeChangeListeners_.end()) {
278         WLOGFE("could not find this listener");
279         return DMError::DM_ERROR_NULLPTR;
280     }
281     screenModeChangeListeners_.erase(iter);
282     return UnregisterScreenModeChangeManagerAgent();
283 }
284 
UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)285 DMError ScreenManagerLite::UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
286 {
287     if (listener == nullptr) {
288         WLOGFE("UnregisterScreenListener listener is nullptr.");
289         return DMError::DM_ERROR_NULLPTR;
290     }
291     return pImpl_->UnregisterScreenModeChangeListener(listener);
292 }
293 
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)294 bool ScreenManagerLite::SetSpecifiedScreenPower(ScreenId screenId,
295     ScreenPowerState state, PowerStateChangeReason reason)
296 {
297     WLOGFI("screenId:%{public}" PRIu64 ", state:%{public}u, reason:%{public}u", screenId, state, reason);
298     return SingletonContainer::Get<ScreenManagerAdapterLite>().SetSpecifiedScreenPower(screenId, state, reason);
299 }
300 
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)301 bool ScreenManagerLite::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
302 {
303     WLOGFI("state:%{public}u, reason:%{public}u", state, reason);
304     return SingletonContainer::Get<ScreenManagerAdapterLite>().SetScreenPowerForAll(state, reason);
305 }
306 
GetScreenPower(ScreenId dmsScreenId)307 ScreenPowerState ScreenManagerLite::GetScreenPower(ScreenId dmsScreenId)
308 {
309     return SingletonContainer::Get<ScreenManagerAdapterLite>().GetScreenPower(dmsScreenId);
310 }
311 
OnRemoteDied()312 void ScreenManagerLite::Impl::OnRemoteDied()
313 {
314     WLOGFD("dms is died");
315     std::lock_guard<std::mutex> lock(mutex_);
316     screenManagerListener_ = nullptr;
317     screenModeChangeListenerAgent_ = nullptr;
318 }
319 
OnRemoteDied()320 void ScreenManagerLite::OnRemoteDied()
321 {
322     pImpl_->OnRemoteDied();
323 }
324 
325 } // namespace OHOS::Rosen