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