1 /*
2 * Copyright (c) 2023 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 "display_manager_lite.h"
17
18 #include <chrono>
19 #include <cinttypes>
20
21 #include "display_manager_adapter_lite.h"
22 #include "display_manager_agent_default.h"
23 #include "dm_common.h"
24 #include "singleton_delegator.h"
25 #include "window_manager_hilog.h"
26
27 namespace OHOS::Rosen {
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DisplayManagerLite"};
30 }
31 WM_IMPLEMENT_SINGLE_INSTANCE(DisplayManagerLite)
32
33 class DisplayManagerLite::Impl : public RefBase {
34 public:
Impl(std::recursive_mutex & mutex)35 Impl(std::recursive_mutex& mutex) : mutex_(mutex) {}
36 ~Impl();
37 static inline SingletonDelegator<DisplayManagerLite> delegator;
38 sptr<DisplayLite> GetDefaultDisplay();
39 FoldStatus GetFoldStatus();
40 FoldDisplayMode GetFoldDisplayMode();
41 bool IsFoldable();
42
43 DMError RegisterDisplayListener(sptr<IDisplayListener> listener);
44 DMError UnregisterDisplayListener(sptr<IDisplayListener> listener);
45 DMError RegisterFoldStatusListener(sptr<IFoldStatusListener> listener);
46 DMError UnregisterFoldStatusListener(sptr<IFoldStatusListener> listener);
47 void OnRemoteDied();
48 private:
49 void NotifyDisplayCreate(sptr<DisplayInfo> info);
50 void NotifyDisplayDestroy(DisplayId);
51 void NotifyDisplayChange(sptr<DisplayInfo> displayInfo);
52 bool UpdateDisplayInfoLocked(sptr<DisplayInfo>);
53 void NotifyFoldStatusChanged(FoldStatus foldStatus);
54 void Clear();
55
56 std::map<DisplayId, sptr<DisplayLite>> displayMap_;
57 std::recursive_mutex& mutex_;
58 std::set<sptr<IDisplayListener>> displayListeners_;
59 std::set<sptr<IFoldStatusListener>> foldStatusListeners_;
60 class DisplayManagerListener;
61 sptr<DisplayManagerListener> displayManagerListener_;
62 class DisplayManagerFoldStatusAgent;
63 sptr<DisplayManagerFoldStatusAgent> foldStatusListenerAgent_;
64 };
65
66 class DisplayManagerLite::Impl::DisplayManagerListener : public DisplayManagerAgentDefault {
67 public:
DisplayManagerListener(sptr<Impl> impl)68 explicit DisplayManagerListener(sptr<Impl> impl) : pImpl_(impl)
69 {
70 }
71
OnDisplayCreate(sptr<DisplayInfo> displayInfo)72 void OnDisplayCreate(sptr<DisplayInfo> displayInfo) override
73 {
74 if (displayInfo == nullptr || displayInfo->GetDisplayId() == DISPLAY_ID_INVALID) {
75 WLOGFE("onDisplayCreate: displayInfo is nullptr");
76 return;
77 }
78 if (pImpl_ == nullptr) {
79 WLOGFE("onDisplayCreate: pImpl_ is nullptr");
80 return;
81 }
82 pImpl_->NotifyDisplayCreate(displayInfo);
83 std::set<sptr<IDisplayListener>> displayListeners;
84 {
85 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
86 displayListeners = pImpl_->displayListeners_;
87 }
88 for (auto listener : displayListeners) {
89 listener->OnCreate(displayInfo->GetDisplayId());
90 }
91 };
92
OnDisplayDestroy(DisplayId displayId)93 void OnDisplayDestroy(DisplayId displayId) override
94 {
95 if (displayId == DISPLAY_ID_INVALID) {
96 WLOGFE("onDisplayDestroy: displayId is invalid");
97 return;
98 }
99 if (pImpl_ == nullptr) {
100 WLOGFE("onDisplayDestroy: impl is nullptr");
101 return;
102 }
103 pImpl_->NotifyDisplayDestroy(displayId);
104 std::set<sptr<IDisplayListener>> displayListeners;
105 {
106 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
107 displayListeners = pImpl_->displayListeners_;
108 }
109 for (auto listener : displayListeners) {
110 listener->OnDestroy(displayId);
111 }
112 };
113
OnDisplayChange(sptr<DisplayInfo> displayInfo,DisplayChangeEvent event)114 void OnDisplayChange(sptr<DisplayInfo> displayInfo, DisplayChangeEvent event) override
115 {
116 if (displayInfo == nullptr || displayInfo->GetDisplayId() == DISPLAY_ID_INVALID) {
117 WLOGFE("onDisplayChange: displayInfo is nullptr");
118 return;
119 }
120 if (pImpl_ == nullptr) {
121 WLOGFE("onDisplayChange: pImpl_ is nullptr");
122 return;
123 }
124 WLOGD("onDisplayChange: display %{public}" PRIu64", event %{public}u", displayInfo->GetDisplayId(), event);
125 pImpl_->NotifyDisplayChange(displayInfo);
126 std::set<sptr<IDisplayListener>> displayListeners;
127 {
128 std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
129 displayListeners = pImpl_->displayListeners_;
130 }
131 for (auto listener : displayListeners) {
132 listener->OnChange(displayInfo->GetDisplayId());
133 }
134 };
135 private:
136 sptr<Impl> pImpl_;
137 };
138
139 class DisplayManagerLite::Impl::DisplayManagerFoldStatusAgent : public DisplayManagerAgentDefault {
140 public:
DisplayManagerFoldStatusAgent(sptr<Impl> impl)141 explicit DisplayManagerFoldStatusAgent(sptr<Impl> impl) : pImpl_(impl)
142 {
143 }
144 ~DisplayManagerFoldStatusAgent() = default;
145
NotifyFoldStatusChanged(FoldStatus foldStatus)146 virtual void NotifyFoldStatusChanged(FoldStatus foldStatus) override
147 {
148 pImpl_->NotifyFoldStatusChanged(foldStatus);
149 }
150 private:
151 sptr<Impl> pImpl_;
152 };
153
Clear()154 void DisplayManagerLite::Impl::Clear()
155 {
156 std::lock_guard<std::recursive_mutex> lock(mutex_);
157 DMError res = DMError::DM_OK;
158 if (displayManagerListener_ != nullptr) {
159 res = SingletonContainer::Get<DisplayManagerAdapterLite>().UnregisterDisplayManagerAgent(
160 displayManagerListener_, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
161 }
162 displayManagerListener_ = nullptr;
163 if (res != DMError::DM_OK) {
164 WLOGFW("UnregisterDisplayManagerAgent DISPLAY_EVENT_LISTENER failed");
165 }
166 }
167
~Impl()168 DisplayManagerLite::Impl::~Impl()
169 {
170 Clear();
171 }
172
DisplayManagerLite()173 DisplayManagerLite::DisplayManagerLite() : pImpl_(new Impl(mutex_))
174 {
175 }
176
~DisplayManagerLite()177 DisplayManagerLite::~DisplayManagerLite()
178 {
179 std::lock_guard<std::recursive_mutex> lock(mutex_);
180 destroyed_ = true;
181 }
182
RegisterDisplayListener(sptr<IDisplayListener> listener)183 DMError DisplayManagerLite::Impl::RegisterDisplayListener(sptr<IDisplayListener> listener)
184 {
185 std::lock_guard<std::recursive_mutex> lock(mutex_);
186 DMError ret = DMError::DM_OK;
187 if (displayManagerListener_ == nullptr) {
188 displayManagerListener_ = new DisplayManagerListener(this);
189 ret = SingletonContainer::Get<DisplayManagerAdapterLite>().RegisterDisplayManagerAgent(
190 displayManagerListener_,
191 DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
192 }
193 if (ret != DMError::DM_OK) {
194 WLOGFW("RegisterDisplayManagerAgent failed");
195 displayManagerListener_ = nullptr;
196 } else {
197 displayListeners_.insert(listener);
198 }
199 return ret;
200 }
201
RegisterDisplayListener(sptr<IDisplayListener> listener)202 DMError DisplayManagerLite::RegisterDisplayListener(sptr<IDisplayListener> listener)
203 {
204 if (listener == nullptr) {
205 WLOGFE("RegisterDisplayListener listener is nullptr");
206 return DMError::DM_ERROR_NULLPTR;
207 }
208 return pImpl_->RegisterDisplayListener(listener);
209 }
210
UnregisterDisplayListener(sptr<IDisplayListener> listener)211 DMError DisplayManagerLite::Impl::UnregisterDisplayListener(sptr<IDisplayListener> listener)
212 {
213 std::lock_guard<std::recursive_mutex> lock(mutex_);
214 auto iter = std::find(displayListeners_.begin(), displayListeners_.end(), listener);
215 if (iter == displayListeners_.end()) {
216 WLOGFE("could not find this listener");
217 return DMError::DM_ERROR_NULLPTR;
218 }
219 displayListeners_.erase(iter);
220 DMError ret = DMError::DM_OK;
221 if (displayListeners_.empty() && displayManagerListener_ != nullptr) {
222 ret = SingletonContainer::Get<DisplayManagerAdapterLite>().UnregisterDisplayManagerAgent(
223 displayManagerListener_,
224 DisplayManagerAgentType::DISPLAY_EVENT_LISTENER);
225 displayManagerListener_ = nullptr;
226 }
227 return ret;
228 }
229
UnregisterDisplayListener(sptr<IDisplayListener> listener)230 DMError DisplayManagerLite::UnregisterDisplayListener(sptr<IDisplayListener> listener)
231 {
232 if (listener == nullptr) {
233 WLOGFE("UnregisterDisplayListener listener is nullptr");
234 return DMError::DM_ERROR_NULLPTR;
235 }
236 return pImpl_->UnregisterDisplayListener(listener);
237 }
238
NotifyDisplayCreate(sptr<DisplayInfo> info)239 void DisplayManagerLite::Impl::NotifyDisplayCreate(sptr<DisplayInfo> info)
240 {
241 std::lock_guard<std::recursive_mutex> lock(mutex_);
242 UpdateDisplayInfoLocked(info);
243 }
244
NotifyDisplayDestroy(DisplayId displayId)245 void DisplayManagerLite::Impl::NotifyDisplayDestroy(DisplayId displayId)
246 {
247 WLOGFD("displayId:%{public}" PRIu64".", displayId);
248 std::lock_guard<std::recursive_mutex> lock(mutex_);
249 displayMap_.erase(displayId);
250 }
251
NotifyDisplayChange(sptr<DisplayInfo> displayInfo)252 void DisplayManagerLite::Impl::NotifyDisplayChange(sptr<DisplayInfo> displayInfo)
253 {
254 std::lock_guard<std::recursive_mutex> lock(mutex_);
255 UpdateDisplayInfoLocked(displayInfo);
256 }
257
UpdateDisplayInfoLocked(sptr<DisplayInfo> displayInfo)258 bool DisplayManagerLite::Impl::UpdateDisplayInfoLocked(sptr<DisplayInfo> displayInfo)
259 {
260 if (displayInfo == nullptr) {
261 WLOGFE("displayInfo is null");
262 return false;
263 }
264 DisplayId displayId = displayInfo->GetDisplayId();
265 WLOGFD("displayId:%{public}" PRIu64".", displayId);
266 if (displayId == DISPLAY_ID_INVALID) {
267 WLOGFE("displayId is invalid");
268 return false;
269 }
270 auto iter = displayMap_.find(displayId);
271 if (iter != displayMap_.end() && iter->second != nullptr) {
272 WLOGFD("get screen in screen map");
273 iter->second->UpdateDisplayInfo(displayInfo);
274 return true;
275 }
276 sptr<DisplayLite> display = new DisplayLite("", displayInfo);
277 displayMap_[displayId] = display;
278 return true;
279 }
280
RegisterFoldStatusListener(sptr<IFoldStatusListener> listener)281 DMError DisplayManagerLite::RegisterFoldStatusListener(sptr<IFoldStatusListener> listener)
282 {
283 if (listener == nullptr) {
284 WLOGFE("IFoldStatusListener listener is nullptr.");
285 return DMError::DM_ERROR_NULLPTR;
286 }
287 return pImpl_->RegisterFoldStatusListener(listener);
288 }
289
RegisterFoldStatusListener(sptr<IFoldStatusListener> listener)290 DMError DisplayManagerLite::Impl::RegisterFoldStatusListener(sptr<IFoldStatusListener> listener)
291 {
292 std::lock_guard<std::recursive_mutex> lock(mutex_);
293 DMError ret = DMError::DM_OK;
294 if (foldStatusListenerAgent_ == nullptr) {
295 foldStatusListenerAgent_ = new DisplayManagerFoldStatusAgent(this);
296 ret = SingletonContainer::Get<DisplayManagerAdapterLite>().RegisterDisplayManagerAgent(
297 foldStatusListenerAgent_,
298 DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
299 }
300 if (ret != DMError::DM_OK) {
301 WLOGFW("RegisterFoldStatusListener failed !");
302 foldStatusListenerAgent_ = nullptr;
303 } else {
304 WLOGI("IFoldStatusListener register success");
305 foldStatusListeners_.insert(listener);
306 }
307 return ret;
308 }
309
UnregisterFoldStatusListener(sptr<IFoldStatusListener> listener)310 DMError DisplayManagerLite::UnregisterFoldStatusListener(sptr<IFoldStatusListener> listener)
311 {
312 if (listener == nullptr) {
313 WLOGFE("UnregisterFoldStatusListener listener is nullptr.");
314 return DMError::DM_ERROR_NULLPTR;
315 }
316 return pImpl_->UnregisterFoldStatusListener(listener);
317 }
318
UnregisterFoldStatusListener(sptr<IFoldStatusListener> listener)319 DMError DisplayManagerLite::Impl::UnregisterFoldStatusListener(sptr<IFoldStatusListener> listener)
320 {
321 std::lock_guard<std::recursive_mutex> lock(mutex_);
322 auto iter = std::find(foldStatusListeners_.begin(), foldStatusListeners_.end(), listener);
323 if (iter == foldStatusListeners_.end()) {
324 WLOGFE("could not find this listener");
325 return DMError::DM_ERROR_NULLPTR;
326 }
327 foldStatusListeners_.erase(iter);
328 DMError ret = DMError::DM_OK;
329 if (foldStatusListeners_.empty() && foldStatusListenerAgent_ != nullptr) {
330 ret = SingletonContainer::Get<DisplayManagerAdapterLite>().UnregisterDisplayManagerAgent(
331 foldStatusListenerAgent_,
332 DisplayManagerAgentType::FOLD_STATUS_CHANGED_LISTENER);
333 foldStatusListenerAgent_ = nullptr;
334 }
335 return ret;
336 }
337
NotifyFoldStatusChanged(FoldStatus foldStatus)338 void DisplayManagerLite::Impl::NotifyFoldStatusChanged(FoldStatus foldStatus)
339 {
340 std::set<sptr<IFoldStatusListener>> foldStatusListeners;
341 {
342 std::lock_guard<std::recursive_mutex> lock(mutex_);
343 foldStatusListeners = foldStatusListeners_;
344 }
345 for (auto& listener : foldStatusListeners) {
346 listener->OnFoldStatusChanged(foldStatus);
347 }
348 }
349
GetFoldStatus()350 FoldStatus DisplayManagerLite::GetFoldStatus()
351 {
352 return pImpl_->GetFoldStatus();
353 }
354
GetFoldStatus()355 FoldStatus DisplayManagerLite::Impl::GetFoldStatus()
356 {
357 return SingletonContainer::Get<DisplayManagerAdapterLite>().GetFoldStatus();
358 }
359
GetDefaultDisplay()360 sptr<DisplayLite> DisplayManagerLite::GetDefaultDisplay()
361 {
362 return pImpl_->GetDefaultDisplay();
363 }
364
GetDefaultDisplay()365 sptr<DisplayLite> DisplayManagerLite::Impl::GetDefaultDisplay()
366 {
367 auto displayInfo = SingletonContainer::Get<DisplayManagerAdapterLite>().GetDefaultDisplayInfo();
368 if (displayInfo == nullptr) {
369 return nullptr;
370 }
371 auto displayId = displayInfo->GetDisplayId();
372 std::lock_guard<std::recursive_mutex> lock(mutex_);
373 if (!UpdateDisplayInfoLocked(displayInfo)) {
374 displayMap_.erase(displayId);
375 return nullptr;
376 }
377 return displayMap_[displayId];
378 }
379
IsFoldable()380 bool DisplayManagerLite::IsFoldable()
381 {
382 return pImpl_->IsFoldable();
383 }
384
IsFoldable()385 bool DisplayManagerLite::Impl::IsFoldable()
386 {
387 return SingletonContainer::Get<DisplayManagerAdapterLite>().IsFoldable();
388 }
389
GetFoldDisplayMode()390 FoldDisplayMode DisplayManagerLite::GetFoldDisplayMode()
391 {
392 return pImpl_->GetFoldDisplayMode();
393 }
394
GetFoldDisplayMode()395 FoldDisplayMode DisplayManagerLite::Impl::GetFoldDisplayMode()
396 {
397 return SingletonContainer::Get<DisplayManagerAdapterLite>().GetFoldDisplayMode();
398 }
399
OnRemoteDied()400 void DisplayManagerLite::Impl::OnRemoteDied()
401 {
402 WLOGFI("dms is died");
403 std::lock_guard<std::recursive_mutex> lock(mutex_);
404 displayManagerListener_ = nullptr;
405 }
406
OnRemoteDied()407 void DisplayManagerLite::OnRemoteDied()
408 {
409 pImpl_->OnRemoteDied();
410 }
411 } // namespace OHOS::Rosen