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
16 #include "screen_manager_lite.h"
17 #include <cinttypes>
18 #include "display_manager_adapter_lite.h"
19 #include "display_manager_agent_default.h"
20 #include "singleton_delegator.h"
21 #include "window_manager_hilog.h"
22
23 namespace OHOS::Rosen {
24
25 /*
26 * used by powermgr
27 */
28 class ScreenManagerLite::Impl : public RefBase {
29 public:
30 Impl() = default;
31 ~Impl();
32
33 static inline SingletonDelegator<ScreenManagerLite> delegator;
34 DMError RegisterScreenListener(sptr<IScreenListener> listener);
35 DMError UnregisterScreenListener(sptr<IScreenListener> listener);
36 DMError RegisterDisplayManagerAgent();
37 DMError UnregisterDisplayManagerAgent();
38 DMError RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener);
39 DMError UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener);
40 DMError RegisterScreenModeChangeManagerAgent();
41 DMError UnregisterScreenModeChangeManagerAgent();
42 DMError RegisterAbnormalScreenConnectChangeListener(sptr<IAbnormalScreenConnectChangeListener> listener);
43 DMError UnregisterAbnormalScreenConnectChangeListener(sptr<IAbnormalScreenConnectChangeListener> listener);
44 DMError GetPhysicalScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos);
45 void OnRemoteDied();
46
47 private:
48 void NotifyScreenConnect(sptr<ScreenInfo> info);
49 void NotifyScreenDisconnect(ScreenId);
50 void NotifyScreenChange(const sptr<ScreenInfo>& screenInfo);
51
52 class ScreenManagerListener;
53 sptr<ScreenManagerListener> screenManagerListener_;
54 std::mutex mutex_;
55 std::set<sptr<IScreenListener>> screenListeners_;
56
57 class ScreenManagerScreenModeChangeAgent;
58 std::set<sptr<IScreenModeChangeListener>> screenModeChangeListeners_;
59 sptr<ScreenManagerScreenModeChangeAgent> screenModeChangeListenerAgent_;
60
61 class ScreenManagerAbnormalScreenConnectChangeAgent;
62 std::set<sptr<IAbnormalScreenConnectChangeListener>> abnormalScreenConnectChangeListeners_;
63 sptr<ScreenManagerAbnormalScreenConnectChangeAgent> abnormalScreenConnectChangeListenerAgent_;
64 };
65
66 class ScreenManagerLite::Impl::ScreenManagerListener : public DisplayManagerAgentDefault {
67 public:
ScreenManagerListener(sptr<Impl> impl)68 explicit ScreenManagerListener(sptr<Impl> impl) : pImpl_(impl)
69 {
70 }
71
OnScreenConnect(sptr<ScreenInfo> screenInfo)72 void OnScreenConnect(sptr<ScreenInfo> screenInfo)
73 {
74 if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) {
75 TLOGE(WmsLogTag::DMS, "screenInfo is invalid.");
76 return;
77 }
78 if (pImpl_ == nullptr) {
79 TLOGE(WmsLogTag::DMS, "impl is nullptr.");
80 return;
81 }
82 std::lock_guard<std::mutex> lock(pImpl_->mutex_);
83 for (auto listener : pImpl_->screenListeners_) {
84 listener->OnConnect(screenInfo->GetScreenId());
85 }
86 };
87
OnScreenDisconnect(ScreenId screenId)88 void OnScreenDisconnect(ScreenId screenId)
89 {
90 if (screenId == SCREEN_ID_INVALID) {
91 TLOGE(WmsLogTag::DMS, "screenId is invalid.");
92 return;
93 }
94 if (pImpl_ == nullptr) {
95 TLOGE(WmsLogTag::DMS, "impl is nullptr.");
96 return;
97 }
98 std::lock_guard<std::mutex> lock(pImpl_->mutex_);
99 for (auto listener : pImpl_->screenListeners_) {
100 listener->OnDisconnect(screenId);
101 }
102 };
103
OnScreenChange(const sptr<ScreenInfo> & screenInfo,ScreenChangeEvent event)104 void OnScreenChange(const sptr<ScreenInfo>& screenInfo, ScreenChangeEvent event)
105 {
106 if (screenInfo == nullptr) {
107 TLOGE(WmsLogTag::DMS, "screenInfo is null.");
108 return;
109 }
110 if (pImpl_ == nullptr) {
111 TLOGE(WmsLogTag::DMS, "impl is nullptr.");
112 return;
113 }
114 TLOGD(WmsLogTag::DMS, "event %{public}u", event);
115 std::lock_guard<std::mutex> lock(pImpl_->mutex_);
116 for (auto listener: pImpl_->screenListeners_) {
117 listener->OnChange(screenInfo->GetScreenId());
118 }
119 };
120 private:
121 sptr<Impl> pImpl_;
122 };
123
124 class ScreenManagerLite::Impl::ScreenManagerScreenModeChangeAgent : public DisplayManagerAgentDefault {
125 public:
ScreenManagerScreenModeChangeAgent(sptr<Impl> impl)126 explicit ScreenManagerScreenModeChangeAgent(sptr<Impl> impl) : pImpl_(impl)
127 {
128 }
129 ~ScreenManagerScreenModeChangeAgent() = default;
130
NotifyScreenModeChange(const std::vector<sptr<ScreenInfo>> & screenInfos)131 virtual void NotifyScreenModeChange(const std::vector<sptr<ScreenInfo>>& screenInfos) override
132 {
133 std::lock_guard<std::mutex> lock(pImpl_->mutex_);
134 for (auto listener: pImpl_->screenModeChangeListeners_) {
135 listener->NotifyScreenModeChange(screenInfos);
136 }
137 }
138 private:
139 sptr<Impl> pImpl_;
140 };
141
142 class ScreenManagerLite::Impl::ScreenManagerAbnormalScreenConnectChangeAgent : public DisplayManagerAgentDefault {
143 public:
ScreenManagerAbnormalScreenConnectChangeAgent(sptr<Impl> impl)144 explicit ScreenManagerAbnormalScreenConnectChangeAgent(sptr<Impl> impl) : pImpl_(impl)
145 {
146 }
147 ~ScreenManagerAbnormalScreenConnectChangeAgent() = default;
148
NotifyAbnormalScreenConnectChange(ScreenId screenId)149 virtual void NotifyAbnormalScreenConnectChange(ScreenId screenId) override
150 {
151 std::lock_guard<std::mutex> lock(pImpl_->mutex_);
152 for (auto listener: pImpl_->abnormalScreenConnectChangeListeners_) {
153 listener->NotifyAbnormalScreenConnectChange(screenId);
154 }
155 }
156 private:
157 sptr<Impl> pImpl_;
158 };
159
WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerLite)160 WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerLite)
161
162 ScreenManagerLite::ScreenManagerLite()
163 {
164 pImpl_ = new Impl();
165 TLOGD(WmsLogTag::DMS, "Create ScreenManagerLite instance");
166 }
167
~ScreenManagerLite()168 ScreenManagerLite::~ScreenManagerLite()
169 {
170 TLOGD(WmsLogTag::DMS, "Destroy ScreenManagerLite instance");
171 }
172
~Impl()173 ScreenManagerLite::Impl::~Impl()
174 {
175 std::lock_guard<std::mutex> lock(mutex_);
176 UnregisterDisplayManagerAgent();
177 }
178
RegisterDisplayManagerAgent()179 DMError ScreenManagerLite::Impl::RegisterDisplayManagerAgent()
180 {
181 DMError regSucc = DMError::DM_OK;
182 if (screenManagerListener_ == nullptr) {
183 screenManagerListener_ = new ScreenManagerListener(this);
184 regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
185 screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
186 if (regSucc != DMError::DM_OK) {
187 screenManagerListener_ = nullptr;
188 TLOGW(WmsLogTag::DMS, "RegisterDisplayManagerAgent failed !");
189 }
190 }
191 return regSucc;
192 }
193
UnregisterDisplayManagerAgent()194 DMError ScreenManagerLite::Impl::UnregisterDisplayManagerAgent()
195 {
196 DMError unRegSucc = DMError::DM_OK;
197 if (screenManagerListener_ != nullptr) {
198 unRegSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
199 screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER);
200 screenManagerListener_ = nullptr;
201 if (unRegSucc != DMError::DM_OK) {
202 TLOGW(WmsLogTag::DMS, "UnregisterDisplayManagerAgent failed!");
203 }
204 }
205 return unRegSucc;
206 }
207
RegisterScreenListener(sptr<IScreenListener> listener)208 DMError ScreenManagerLite::Impl::RegisterScreenListener(sptr<IScreenListener> listener)
209 {
210 std::lock_guard<std::mutex> lock(mutex_);
211 DMError regSucc = RegisterDisplayManagerAgent();
212 if (regSucc == DMError::DM_OK) {
213 screenListeners_.insert(listener);
214 }
215 return regSucc;
216 }
217
RegisterScreenListener(sptr<IScreenListener> listener)218 DMError ScreenManagerLite::RegisterScreenListener(sptr<IScreenListener> listener)
219 {
220 if (listener == nullptr) {
221 TLOGE(WmsLogTag::DMS, "listener is nullptr.");
222 return DMError::DM_ERROR_NULLPTR;
223 }
224 return pImpl_->RegisterScreenListener(listener);
225 }
226
UnregisterScreenListener(sptr<IScreenListener> listener)227 DMError ScreenManagerLite::Impl::UnregisterScreenListener(sptr<IScreenListener> listener)
228 {
229 std::lock_guard<std::mutex> lock(mutex_);
230 auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener);
231 if (iter == screenListeners_.end()) {
232 TLOGE(WmsLogTag::DMS, "could not find this listener");
233 return DMError::DM_ERROR_NULLPTR;
234 }
235 screenListeners_.erase(iter);
236 return UnregisterDisplayManagerAgent();
237 }
238
UnregisterScreenListener(sptr<IScreenListener> listener)239 DMError ScreenManagerLite::UnregisterScreenListener(sptr<IScreenListener> listener)
240 {
241 if (listener == nullptr) {
242 TLOGE(WmsLogTag::DMS, "listener is nullptr.");
243 return DMError::DM_ERROR_NULLPTR;
244 }
245 return pImpl_->UnregisterScreenListener(listener);
246 }
247
RegisterScreenModeChangeManagerAgent()248 DMError ScreenManagerLite::Impl::RegisterScreenModeChangeManagerAgent()
249 {
250 DMError regSucc = DMError::DM_OK;
251 if (screenModeChangeListenerAgent_ == nullptr) {
252 screenModeChangeListenerAgent_ = new ScreenManagerScreenModeChangeAgent(this);
253 regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
254 screenModeChangeListenerAgent_, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
255 if (regSucc != DMError::DM_OK) {
256 screenModeChangeListenerAgent_ = nullptr;
257 TLOGW(WmsLogTag::DMS, "RegisterDisplayManagerAgent failed !");
258 }
259 }
260 return regSucc;
261 }
262
UnregisterScreenModeChangeManagerAgent()263 DMError ScreenManagerLite::Impl::UnregisterScreenModeChangeManagerAgent()
264 {
265 DMError unRegSucc = DMError::DM_OK;
266 if (screenModeChangeListenerAgent_ != nullptr) {
267 unRegSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
268 screenModeChangeListenerAgent_, DisplayManagerAgentType::SCREEN_MODE_CHANGE_EVENT_LISTENER);
269 screenModeChangeListenerAgent_ = nullptr;
270 if (unRegSucc != DMError::DM_OK) {
271 TLOGW(WmsLogTag::DMS, "UnregisterDisplayManagerAgent failed!");
272 }
273 }
274 return unRegSucc;
275 }
276
RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)277 DMError ScreenManagerLite::Impl::RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
278 {
279 std::lock_guard<std::mutex> lock(mutex_);
280 DMError regSucc = RegisterScreenModeChangeManagerAgent();
281 if (regSucc == DMError::DM_OK) {
282 screenModeChangeListeners_.insert(listener);
283 }
284 std::vector<sptr<ScreenInfo>> screenInfos;
285 DMError ret = GetPhysicalScreenInfos(screenInfos);
286 if (ret == DMError::DM_OK) {
287 TLOGI(WmsLogTag::DMS, "RegisterScreenListener notify");
288 listener->NotifyScreenModeChange(screenInfos);
289 }
290 return regSucc;
291 }
292
RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)293 DMError ScreenManagerLite::RegisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
294 {
295 if (listener == nullptr) {
296 TLOGE(WmsLogTag::DMS, "listener is nullptr.");
297 return DMError::DM_ERROR_NULLPTR;
298 }
299 return pImpl_->RegisterScreenModeChangeListener(listener);
300 }
301
UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)302 DMError ScreenManagerLite::Impl::UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
303 {
304 std::lock_guard<std::mutex> lock(mutex_);
305 auto iter = std::find(screenModeChangeListeners_.begin(), screenModeChangeListeners_.end(), listener);
306 if (iter == screenModeChangeListeners_.end()) {
307 TLOGE(WmsLogTag::DMS, "could not find this listener");
308 return DMError::DM_ERROR_NULLPTR;
309 }
310 screenModeChangeListeners_.erase(iter);
311 return UnregisterScreenModeChangeManagerAgent();
312 }
313
UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)314 DMError ScreenManagerLite::UnregisterScreenModeChangeListener(sptr<IScreenModeChangeListener> listener)
315 {
316 if (listener == nullptr) {
317 TLOGE(WmsLogTag::DMS, "listener is nullptr.");
318 return DMError::DM_ERROR_NULLPTR;
319 }
320 return pImpl_->UnregisterScreenModeChangeListener(listener);
321 }
322
RegisterAbnormalScreenConnectChangeListener(sptr<IAbnormalScreenConnectChangeListener> listener)323 DMError ScreenManagerLite::RegisterAbnormalScreenConnectChangeListener(
324 sptr<IAbnormalScreenConnectChangeListener> listener)
325 {
326 if (listener == nullptr) {
327 TLOGE(WmsLogTag::DMS, "listener is nullptr.");
328 return DMError::DM_ERROR_NULLPTR;
329 }
330 return pImpl_->RegisterAbnormalScreenConnectChangeListener(listener);
331 }
332
RegisterAbnormalScreenConnectChangeListener(sptr<IAbnormalScreenConnectChangeListener> listener)333 DMError ScreenManagerLite::Impl::RegisterAbnormalScreenConnectChangeListener(
334 sptr<IAbnormalScreenConnectChangeListener> listener)
335 {
336 std::lock_guard<std::mutex> lock(mutex_);
337 DMError regSucc = DMError::DM_OK;
338 if (abnormalScreenConnectChangeListenerAgent_ == nullptr) {
339 abnormalScreenConnectChangeListenerAgent_ =
340 new (std::nothrow) ScreenManagerAbnormalScreenConnectChangeAgent(this);
341 regSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().RegisterDisplayManagerAgent(
342 abnormalScreenConnectChangeListenerAgent_,
343 DisplayManagerAgentType::ABNORMAL_SCREEN_CONNECT_CHANGE_LISTENER);
344 if (regSucc != DMError::DM_OK) {
345 abnormalScreenConnectChangeListenerAgent_ = nullptr;
346 TLOGW(WmsLogTag::DMS, "RegisterDisplayManagerAgent failed !");
347 }
348 }
349 if (regSucc == DMError::DM_OK) {
350 abnormalScreenConnectChangeListeners_.insert(listener);
351 }
352 return regSucc;
353 }
354
UnregisterAbnormalScreenConnectChangeListener(sptr<IAbnormalScreenConnectChangeListener> listener)355 DMError ScreenManagerLite::UnregisterAbnormalScreenConnectChangeListener(
356 sptr<IAbnormalScreenConnectChangeListener> listener)
357 {
358 if (listener == nullptr) {
359 TLOGE(WmsLogTag::DMS, "listener is nullptr.");
360 return DMError::DM_ERROR_NULLPTR;
361 }
362 return pImpl_->UnregisterAbnormalScreenConnectChangeListener(listener);
363 }
364
UnregisterAbnormalScreenConnectChangeListener(sptr<IAbnormalScreenConnectChangeListener> listener)365 DMError ScreenManagerLite::Impl::UnregisterAbnormalScreenConnectChangeListener(
366 sptr<IAbnormalScreenConnectChangeListener> listener)
367 {
368 std::lock_guard<std::mutex> lock(mutex_);
369 auto iter = std::find(abnormalScreenConnectChangeListeners_.begin(),
370 abnormalScreenConnectChangeListeners_.end(), listener);
371 if (iter == abnormalScreenConnectChangeListeners_.end()) {
372 TLOGE(WmsLogTag::DMS, "could not find this listener");
373 return DMError::DM_ERROR_NULLPTR;
374 }
375 abnormalScreenConnectChangeListeners_.erase(iter);
376 DMError unregSucc = DMError::DM_OK;
377 if (abnormalScreenConnectChangeListenerAgent_ != nullptr) {
378 unregSucc = SingletonContainer::Get<ScreenManagerAdapterLite>().UnregisterDisplayManagerAgent(
379 abnormalScreenConnectChangeListenerAgent_,
380 DisplayManagerAgentType::ABNORMAL_SCREEN_CONNECT_CHANGE_LISTENER);
381 abnormalScreenConnectChangeListenerAgent_ = nullptr;
382 if (unregSucc != DMError::DM_OK) {
383 TLOGW(WmsLogTag::DMS, "UnregisterDisplayManagerAgent failed !");
384 }
385 }
386 return unregSucc;
387 }
388
SetSpecifiedScreenPower(ScreenId screenId,ScreenPowerState state,PowerStateChangeReason reason)389 bool ScreenManagerLite::SetSpecifiedScreenPower(ScreenId screenId,
390 ScreenPowerState state, PowerStateChangeReason reason)
391 {
392 TLOGI(WmsLogTag::DMS, "screenId:%{public}" PRIu64 ", state:%{public}u, reason:%{public}u", screenId, state, reason);
393 return SingletonContainer::Get<ScreenManagerAdapterLite>().SetSpecifiedScreenPower(screenId, state, reason);
394 }
395
SetScreenPowerForAll(ScreenPowerState state,PowerStateChangeReason reason)396 bool ScreenManagerLite::SetScreenPowerForAll(ScreenPowerState state, PowerStateChangeReason reason)
397 {
398 TLOGI(WmsLogTag::DMS, "state:%{public}u, reason:%{public}u", state, reason);
399 return SingletonContainer::Get<ScreenManagerAdapterLite>().SetScreenPowerForAll(state, reason);
400 }
401
GetScreenPower(ScreenId dmsScreenId)402 ScreenPowerState ScreenManagerLite::GetScreenPower(ScreenId dmsScreenId)
403 {
404 return SingletonContainer::Get<ScreenManagerAdapterLite>().GetScreenPower(dmsScreenId);
405 }
406
GetScreenPower()407 ScreenPowerState ScreenManagerLite::GetScreenPower()
408 {
409 return SingletonContainer::Get<ScreenManagerAdapterLite>().GetScreenPower();
410 }
411
GetPhysicalScreenIds(std::vector<ScreenId> & screenIds)412 DMError ScreenManagerLite::GetPhysicalScreenIds(std::vector<ScreenId>& screenIds)
413 {
414 TLOGI(WmsLogTag::DMS, "enter");
415 DMError ret = SingletonContainer::Get<ScreenManagerAdapterLite>().GetPhysicalScreenIds(screenIds);
416 if (ret != DMError::DM_OK) {
417 TLOGE(WmsLogTag::DMS, "failed");
418 return ret;
419 }
420 return DMError::DM_OK;
421 }
422
GetPhysicalScreenInfos(std::vector<sptr<ScreenInfo>> & screenInfos)423 DMError ScreenManagerLite::Impl::GetPhysicalScreenInfos(std::vector<sptr<ScreenInfo>>& screenInfos)
424 {
425 std::vector<sptr<ScreenInfo>> allScreenInfos;
426 DMError ret = SingletonContainer::Get<ScreenManagerAdapterLite>().GetAllScreenInfos(allScreenInfos);
427 if (ret != DMError::DM_OK) {
428 TLOGE(WmsLogTag::DMS, "GetPhysicalScreenInfos failed");
429 return ret;
430 }
431 for (const auto& screenInfo : allScreenInfos) {
432 if (screenInfo->GetType() == ScreenType::REAL) {
433 screenInfos.push_back(screenInfo);
434 }
435 }
436 return DMError::DM_OK;
437 }
438
GetScreenInfoById(ScreenId screenId)439 sptr<ScreenInfo> ScreenManagerLite::GetScreenInfoById(ScreenId screenId)
440 {
441 return SingletonContainer::Get<ScreenManagerAdapterLite>().GetScreenInfo(screenId);
442 }
443
OnRemoteDied()444 void ScreenManagerLite::Impl::OnRemoteDied()
445 {
446 TLOGD(WmsLogTag::DMS, "dms is died");
447 std::lock_guard<std::mutex> lock(mutex_);
448 screenManagerListener_ = nullptr;
449 screenModeChangeListenerAgent_ = nullptr;
450 abnormalScreenConnectChangeListenerAgent_ = nullptr;
451 }
452
OnRemoteDied()453 void ScreenManagerLite::OnRemoteDied()
454 {
455 pImpl_->OnRemoteDied();
456 }
457
SynchronizePowerStatus(ScreenPowerState state)458 bool ScreenManagerLite::SynchronizePowerStatus(ScreenPowerState state)
459 {
460 TLOGD(WmsLogTag::DMS, "state: %{public}u", state);
461 return SingletonContainer::Get<ScreenManagerAdapterLite>().SynchronizePowerStatus(state);
462 }
463
464 } // namespace OHOS::Rosen