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 "cj_display_impl.h"
17
18 #include <map>
19 #include <securec.h>
20
21 #include "cj_display_listener.h"
22 #include "cutout_info.h"
23 #include "display.h"
24 #include "display_info.h"
25 #include "display_utils.h"
26 #include "singleton_container.h"
27 #include "window_manager_hilog.h"
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace {
32 const std::map<DisplayState, DisplayStateMode> NATIVE_TO_CJ_DISPLAY_STATE_MAP {
33 { DisplayState::UNKNOWN, DisplayStateMode::STATE_UNKNOWN },
34 { DisplayState::OFF, DisplayStateMode::STATE_OFF },
35 { DisplayState::ON, DisplayStateMode::STATE_ON },
36 { DisplayState::DOZE, DisplayStateMode::STATE_DOZE },
37 { DisplayState::DOZE_SUSPEND, DisplayStateMode::STATE_DOZE_SUSPEND },
38 { DisplayState::VR, DisplayStateMode::STATE_VR },
39 { DisplayState::ON_SUSPEND, DisplayStateMode::STATE_ON_SUSPEND },
40 };
41 }
42 static thread_local std::map<uint64_t, sptr<DisplayImpl>> g_cjDisplayMap;
43 std::map<std::string, std::map<int64_t, sptr<CJDisplayListener>>> g_cjCbMap;
44 std::mutex g_mtx;
45 std::recursive_mutex g_mutex;
46
SetCRect(const DMRect & row,CRect * ptr)47 void SetCRect(const DMRect& row, CRect* ptr)
48 {
49 ptr->left = row.posX_;
50 ptr->top = row.posY_;
51 ptr->width = row.width_;
52 ptr->height = row.height_;
53 }
54
CreateColorSpacesObject(std::vector<uint32_t> & colorSpaces)55 uint32_t* CreateColorSpacesObject(std::vector<uint32_t>& colorSpaces)
56 {
57 uint32_t* colorSpacesPtr = static_cast<uint32_t*>(malloc(colorSpaces.size() * sizeof(uint32_t)));
58 if (!colorSpacesPtr) {
59 return nullptr;
60 }
61 std::copy(colorSpaces.begin(), colorSpaces.end(), colorSpacesPtr);
62 return colorSpacesPtr;
63 }
64
CreateHdrFormatsObject(std::vector<uint32_t> & hdrFormats)65 uint32_t* CreateHdrFormatsObject(std::vector<uint32_t>& hdrFormats)
66 {
67 uint32_t* hdrFormatsPtr = static_cast<uint32_t*>(malloc(hdrFormats.size() * sizeof(uint32_t)));
68 if (!hdrFormatsPtr) {
69 return nullptr;
70 }
71 std::copy(hdrFormats.begin(), hdrFormats.end(), hdrFormatsPtr);
72 return hdrFormatsPtr;
73 }
74
CreateCBoundingRects(std::vector<DMRect> & bound)75 CRect* CreateCBoundingRects(std::vector<DMRect>& bound)
76 {
77 int32_t number = static_cast<int32_t>(bound.size());
78 CRect* result = static_cast<CRect*>(malloc(sizeof(CRect) * number));
79 if (result == nullptr) {
80 TLOGE(WmsLogTag::DMS, "[CreateCBoundingRects] memory failed.");
81 return nullptr;
82 }
83 for (int i = 0; i < number; i++) {
84 SetCRect(bound[i], (result + i));
85 }
86 return result;
87 }
88
SetCWaterfallDisplayAreaRects(const WaterfallDisplayAreaRects & area,CCutoutInfo * info)89 void SetCWaterfallDisplayAreaRects(const WaterfallDisplayAreaRects& area, CCutoutInfo* info)
90 {
91 if (info == nullptr || info->boundingRects == nullptr) {
92 return;
93 }
94 SetCRect(area.left, &(info->waterfallDisplayAreaRects.left));
95 SetCRect(area.top, &(info->waterfallDisplayAreaRects.top));
96 SetCRect(area.right, &(info->waterfallDisplayAreaRects.right));
97 SetCRect(area.bottom, &(info->waterfallDisplayAreaRects.bottom));
98 }
99
CreateCCutoutInfoObject(sptr<CutoutInfo> & cutoutInfo)100 CCutoutInfo* CreateCCutoutInfoObject(sptr<CutoutInfo>& cutoutInfo)
101 {
102 CCutoutInfo* info = static_cast<CCutoutInfo*>(malloc(sizeof(CCutoutInfo)));
103 if (info == nullptr) {
104 return nullptr;
105 }
106 std::vector<DMRect> boundingRects = cutoutInfo->GetBoundingRects();
107 WaterfallDisplayAreaRects waterfallDisplayAreaRects = cutoutInfo->GetWaterfallDisplayAreaRects();
108 info->number = static_cast<int64_t>(boundingRects.size());
109 info->boundingRects = CreateCBoundingRects(boundingRects);
110 if (info->boundingRects == nullptr) {
111 TLOGE(WmsLogTag::DMS, "[CreateCCutoutInfoObject] memory failed.");
112 free(info);
113 return nullptr;
114 }
115 SetCWaterfallDisplayAreaRects(waterfallDisplayAreaRects, info);
116 return info;
117 }
118
FindDisplayObject(uint64_t displayId)119 sptr<DisplayImpl> DisplayImpl::FindDisplayObject(uint64_t displayId)
120 {
121 std::lock_guard<std::recursive_mutex> lock(g_mutex);
122 if (g_cjDisplayMap.find(displayId) == g_cjDisplayMap.end()) {
123 TLOGI(WmsLogTag::DMS, "[FindDisplayObject] Can not find display %{public}" PRIu64 " in display map", displayId);
124 return nullptr;
125 }
126 return g_cjDisplayMap[displayId];
127 }
128
DisplayImpl(const sptr<Display> & display)129 DisplayImpl::DisplayImpl(const sptr<Display>& display) : display_(display) {}
130
~DisplayImpl()131 DisplayImpl::~DisplayImpl()
132 {
133 uint64_t displayId = display_->GetId();
134 sptr<DisplayImpl> cjDisplayPtr = DisplayImpl::FindDisplayObject(displayId);
135 if (cjDisplayPtr == nullptr) {
136 return;
137 }
138 std::lock_guard<std::recursive_mutex> lock(g_mutex);
139 g_cjDisplayMap.erase(displayId);
140 return;
141 }
142
CreateDisplayImpl(sptr<Display> & display)143 sptr<DisplayImpl> DisplayImpl::CreateDisplayImpl(sptr<Display>& display)
144 {
145 uint64_t displayId = display->GetId();
146 sptr<DisplayImpl> cjDisplayPtr = DisplayImpl::FindDisplayObject(displayId);
147 auto info = display->GetDisplayInfo();
148 if (info == nullptr) {
149 TLOGE(WmsLogTag::DMS, "[CreateDisplayImpl] Failed to get display info");
150 return nullptr;
151 }
152 if (cjDisplayPtr == nullptr) {
153 cjDisplayPtr = FFIData::Create<DisplayImpl>(display);
154 if (cjDisplayPtr == nullptr) {
155 TLOGE(WmsLogTag::DMS, "[CreateDisplayImpl] Failed to create display");
156 return nullptr;
157 }
158 std::lock_guard<std::recursive_mutex> lock(g_mutex);
159 g_cjDisplayMap[displayId] = cjDisplayPtr;
160 }
161 return cjDisplayPtr;
162 }
163
GetInfoId()164 uint32_t DisplayImpl::GetInfoId()
165 {
166 auto info = display_->GetDisplayInfo();
167 if (info == nullptr) {
168 TLOGE(WmsLogTag::DMS, "[GetInfoId] Failed to get display info");
169 return static_cast<uint32_t>(DISPLAY_ID_INVALID);
170 }
171 return static_cast<uint32_t>(info->GetDisplayId());
172 }
173
GetName()174 char* DisplayImpl::GetName()
175 {
176 auto info = display_->GetDisplayInfo();
177 if (info == nullptr) {
178 TLOGE(WmsLogTag::DMS, "[GetName] Failed to get display info");
179 return nullptr;
180 }
181 auto name = info->GetName();
182 int len = static_cast<int>(name.length());
183 char* retData = static_cast<char*>(malloc(len + 1));
184 if (retData == nullptr) {
185 return nullptr;
186 }
187 int ret = memcpy_s(retData, len + 1, name.c_str(), len + 1);
188 if (ret != 0) {
189 TLOGE(WmsLogTag::DMS, "[DisplayImpl] Failed to get name");
190 free(retData);
191 retData = nullptr;
192 }
193 return retData;
194 }
195
GetAlive()196 bool DisplayImpl::GetAlive()
197 {
198 auto info = display_->GetDisplayInfo();
199 if (info == nullptr) {
200 TLOGE(WmsLogTag::DMS, "[GetAlive] Failed to get display info");
201 return false;
202 }
203 return info->GetAliveStatus();
204 }
205
GetState()206 uint32_t DisplayImpl::GetState()
207 {
208 auto info = display_->GetDisplayInfo();
209 if (info == nullptr) {
210 TLOGE(WmsLogTag::DMS, "[GetState] Failed to get display info");
211 return static_cast<uint32_t>(DisplayStateMode::STATE_UNKNOWN);
212 }
213 auto state = info->GetDisplayState();
214 if (NATIVE_TO_CJ_DISPLAY_STATE_MAP.count(state) != 0) {
215 return static_cast<uint32_t>(NATIVE_TO_CJ_DISPLAY_STATE_MAP.at(state));
216 } else {
217 return static_cast<uint32_t>(DisplayStateMode::STATE_UNKNOWN);
218 }
219 }
220
GetRefreshRate()221 uint32_t DisplayImpl::GetRefreshRate()
222 {
223 auto info = display_->GetDisplayInfo();
224 if (info == nullptr) {
225 TLOGE(WmsLogTag::DMS, "[GetRefreshRate] Failed to get display info");
226 return 0;
227 }
228 return info->GetRefreshRate();
229 }
230
GetRotation()231 uint32_t DisplayImpl::GetRotation()
232 {
233 auto info = display_->GetDisplayInfo();
234 if (info == nullptr) {
235 TLOGE(WmsLogTag::DMS, "[GetRotation] Failed to get display info");
236 return 0;
237 }
238 return static_cast<uint32_t>(info->GetRotation());
239 }
240
GetOrientation()241 uint32_t DisplayImpl::GetOrientation()
242 {
243 auto info = display_->GetDisplayInfo();
244 if (info == nullptr) {
245 TLOGE(WmsLogTag::DMS, "[GetOrientation] Failed to get display info");
246 return 0;
247 }
248 return static_cast<uint32_t>(info->GetDisplayOrientation());
249 }
250
GetWidth()251 int32_t DisplayImpl::GetWidth()
252 {
253 auto info = display_->GetDisplayInfo();
254 if (info == nullptr) {
255 TLOGE(WmsLogTag::DMS, "[GetWidth] Failed to get display info");
256 return 0;
257 }
258 return info->GetWidth();
259 }
260
GetHeight()261 int32_t DisplayImpl::GetHeight()
262 {
263 auto info = display_->GetDisplayInfo();
264 if (info == nullptr) {
265 TLOGE(WmsLogTag::DMS, "[GetHeight] Failed to get display info");
266 return 0;
267 }
268 return info->GetHeight();
269 }
270
GetDensityDPI()271 float DisplayImpl::GetDensityDPI()
272 {
273 auto info = display_->GetDisplayInfo();
274 if (info == nullptr) {
275 TLOGE(WmsLogTag::DMS, "[GetDensityDPI] Failed to get display info");
276 return 1.0 * DOT_PER_INCH;
277 }
278 return info->GetVirtualPixelRatio() * DOT_PER_INCH;
279 }
280
GetVirtualPixelRatio()281 float DisplayImpl::GetVirtualPixelRatio()
282 {
283 auto info = display_->GetDisplayInfo();
284 if (info == nullptr) {
285 TLOGE(WmsLogTag::DMS, "[GetVirtualPixelRatio] Failed to get display info");
286 return 1.0;
287 }
288 return info->GetVirtualPixelRatio();
289 }
290
GetXDPI()291 float DisplayImpl::GetXDPI()
292 {
293 auto info = display_->GetDisplayInfo();
294 if (info == nullptr) {
295 TLOGE(WmsLogTag::DMS, "[GetXDPI] Failed to get display info");
296 return 0.0;
297 }
298 return info->GetXDpi();
299 }
300
GetYDPI()301 float DisplayImpl::GetYDPI()
302 {
303 auto info = display_->GetDisplayInfo();
304 if (info == nullptr) {
305 TLOGE(WmsLogTag::DMS, "[GetYDPI] Failed to get display info");
306 return 0.0;
307 }
308 return info->GetYDpi();
309 }
310
GetColorSpaces()311 RetStruct DisplayImpl::GetColorSpaces()
312 {
313 auto info = display_->GetDisplayInfo();
314 if (info == nullptr) {
315 TLOGE(WmsLogTag::DMS, "[GetColorSpaces] Failed to get display info");
316 return {};
317 }
318 auto colorSpaces = info->GetColorSpaces();
319 RetStruct result = {
320 .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr
321 };
322 result.data = CreateColorSpacesObject(colorSpaces);
323 result.code = static_cast<int32_t>(DmErrorCode::DM_OK);
324 if (result.data == nullptr) {
325 result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL);
326 }
327 result.len = static_cast<int64_t>(colorSpaces.size());
328 return result;
329 }
330
GetHdrFormats()331 RetStruct DisplayImpl::GetHdrFormats()
332 {
333 auto info = display_->GetDisplayInfo();
334 if (info == nullptr) {
335 TLOGE(WmsLogTag::DMS, "[GetHdrFormats] Failed to get display info");
336 return {};
337 }
338 auto hdrFormats = info->GetHdrFormats();
339 RetStruct result = {
340 .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr
341 };
342 result.data = CreateHdrFormatsObject(hdrFormats);
343 result.code = static_cast<int32_t>(DmErrorCode::DM_OK);
344 if (result.data == nullptr) {
345 result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL);
346 }
347 result.len = static_cast<int64_t>(hdrFormats.size());
348 return result;
349 }
350
GetAvailableWidth()351 uint32_t DisplayImpl::GetAvailableWidth()
352 {
353 auto info = display_->GetDisplayInfo();
354 if (info == nullptr) {
355 TLOGE(WmsLogTag::DMS, "[GetAvailableWidth] Failed to get display info");
356 return 0;
357 }
358 return info->GetAvailableWidth();
359 }
360
GetAvailableHeight()361 uint32_t DisplayImpl::GetAvailableHeight()
362 {
363 auto info = display_->GetDisplayInfo();
364 if (info == nullptr) {
365 TLOGE(WmsLogTag::DMS, "[GetAvailableHeight] Failed to get display info");
366 return 0;
367 }
368 return info->GetAvailableHeight();
369 }
370
GetCutoutInfo()371 RetStruct DisplayImpl::GetCutoutInfo()
372 {
373 RetStruct result = {
374 .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr
375 };
376 sptr<CutoutInfo> cutoutInfo = display_->GetCutoutInfo();
377 if (cutoutInfo == nullptr) {
378 result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN);
379 return result;
380 }
381 result.data = CreateCCutoutInfoObject(cutoutInfo);
382 result.code = static_cast<int32_t>(DmErrorCode::DM_OK);
383 if (result.data == nullptr) {
384 result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL);
385 }
386 return result;
387 }
388
GetAvailableArea()389 RetStruct DisplayImpl::GetAvailableArea()
390 {
391 RetStruct result = {
392 .code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr
393 };
394 DMRect area;
395 DmErrorCode errorCode = DM_JS_TO_ERROR_CODE_MAP.at(display_->GetAvailableArea(area));
396 if (errorCode != DmErrorCode::DM_OK) {
397 result.code = static_cast<int32_t>(errorCode);
398 TLOGE(WmsLogTag::DMS, "GetAvailableArea failed!");
399 return result;
400 }
401 result.data = static_cast<CRect*>(malloc(sizeof(CRect)));
402 if (result.data == nullptr) {
403 result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL);
404 TLOGE(WmsLogTag::DMS, "GetAvailableArea failed!");
405 return result;
406 }
407 SetCRect(area, static_cast<CRect*>(result.data));
408 result.code = static_cast<int32_t>(DmErrorCode::DM_OK);
409 return result;
410 }
411
IfCallbackRegistered(const std::string & type,int64_t funcId)412 bool IfCallbackRegistered(const std::string& type, int64_t funcId)
413 {
414 if (g_cjCbMap.empty() || g_cjCbMap.find(type) == g_cjCbMap.end()) {
415 TLOGI(WmsLogTag::DMS, "IfCallbackRegistered methodName %{public}s not registered!", type.c_str());
416 return false;
417 }
418
419 for (auto& iter : g_cjCbMap[type]) {
420 if (iter.first == funcId) {
421 TLOGE(WmsLogTag::DMS, "IfCallbackRegistered callback already registered!");
422 return true;
423 }
424 }
425 return false;
426 }
427
OnUnRegisterAllDisplayManagerCallback(const std::string & type)428 int32_t DisplayImpl::OnUnRegisterAllDisplayManagerCallback(const std::string& type)
429 {
430 std::lock_guard<std::mutex> lock(g_mtx);
431 TLOGD(WmsLogTag::DMS, "DisplayImpl::OnUnRegisterDisplayManagerCallbackWithType is called");
432 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterAllDisplayListenerWithType(type));
433 if (ret != DmErrorCode::DM_OK) {
434 TLOGE(WmsLogTag::DMS, "Failed to unregister display listener with type %{public}s.", type.c_str());
435 ret = DmErrorCode::DM_ERROR_INVALID_PARAM;
436 }
437 return static_cast<int32_t>(ret);
438 }
439
UnRegisterAllDisplayListenerWithType(const std::string & type)440 DMError DisplayImpl::UnRegisterAllDisplayListenerWithType(const std::string& type)
441 {
442 TLOGD(WmsLogTag::DMS, "DisplayImpl::UnRegisterDisplayManagerListenerWithType is called");
443 if (g_cjCbMap.empty() || g_cjCbMap.find(type) == g_cjCbMap.end()) {
444 TLOGI(WmsLogTag::DMS, "UnRegisterDisplayManagerListenerWithType methodName %{public}s not registered",
445 type.c_str());
446 return DMError::DM_OK;
447 }
448 DMError ret = DMError::DM_OK;
449 for (auto it = g_cjCbMap[type].begin(); it != g_cjCbMap[type].end();) {
450 it->second->RemoveAllCallback();
451 if (type == EVENT_AVAILABLE_AREA_CHANGED) {
452 sptr<DisplayManager::IAvailableAreaListener> thisListener(it->second);
453 ret = SingletonContainer::Get<DisplayManager>().UnregisterAvailableAreaListener(thisListener);
454 } else {
455 ret = DMError::DM_ERROR_INVALID_PARAM;
456 }
457 g_cjCbMap[type].erase(it++);
458 }
459 g_cjCbMap.erase(type);
460 return ret;
461 }
462
OnRegisterDisplayManagerCallback(const std::string & type,int64_t funcId)463 int32_t DisplayImpl::OnRegisterDisplayManagerCallback(const std::string& type, int64_t funcId)
464 {
465 std::lock_guard<std::mutex> lock(g_mtx);
466 TLOGD(WmsLogTag::DMS, "DisplayImpl::OnRegisterDisplayManagerCallback is called");
467 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(RegisterDisplayListenerWithType(type, funcId));
468 if (ret != DmErrorCode::DM_OK) {
469 TLOGE(WmsLogTag::DMS, "Failed to register display listener with type %{public}s", type.c_str());
470 ret = DmErrorCode::DM_ERROR_INVALID_PARAM;
471 }
472 return static_cast<int32_t>(ret);
473 }
474
RegisterDisplayListenerWithType(const std::string & type,int64_t funcId)475 DMError DisplayImpl::RegisterDisplayListenerWithType(const std::string& type, int64_t funcId)
476 {
477 TLOGD(WmsLogTag::DMS, "DisplayImpl::RegisterDisplayListenerWithType is called");
478 if (IfCallbackRegistered(type, funcId)) {
479 TLOGI(WmsLogTag::DMS, "RegisterDisplayListenerWithType callback already registered!");
480 return DMError::DM_OK;
481 }
482 sptr<CJDisplayListener> displayListener = new (std::nothrow) CJDisplayListener();
483 DMError ret = DMError::DM_OK;
484 if (displayListener == nullptr) {
485 TLOGE(WmsLogTag::DMS, "displayListener is nullptr");
486 return DMError::DM_ERROR_INVALID_PARAM;
487 }
488 if (type == EVENT_AVAILABLE_AREA_CHANGED) {
489 ret = SingletonContainer::Get<DisplayManager>().RegisterAvailableAreaListener(displayListener);
490 } else {
491 TLOGI(WmsLogTag::DMS, "RegisterDisplayListenerWithType failed, %{public}s not support", type.c_str());
492 return DMError::DM_ERROR_INVALID_PARAM;
493 }
494 if (ret != DMError::DM_OK) {
495 TLOGE(WmsLogTag::DMS, "RegisterDisplayListenerWithType failed, ret: %{public}u", ret);
496 return ret;
497 }
498 displayListener->AddCallback(type, funcId);
499 g_cjCbMap[type][funcId] = displayListener;
500 return DMError::DM_OK;
501 }
502
OnUnRegisterDisplayManagerCallback(const std::string & type,int64_t funcId)503 int32_t DisplayImpl::OnUnRegisterDisplayManagerCallback(const std::string& type, int64_t funcId)
504 {
505 std::lock_guard<std::mutex> lock(g_mtx);
506 TLOGD(WmsLogTag::DMS, "DisplayImpl::OnUnRegisterDisplayManagerCallback is called");
507 DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterDisplayListenerWithType(type, funcId));
508 if (ret != DmErrorCode::DM_OK) {
509 TLOGE(WmsLogTag::DMS, "Failed to unregister display listener with type %{public}s", type.c_str());
510 ret = DmErrorCode::DM_ERROR_INVALID_PARAM;
511 }
512 return static_cast<int32_t>(ret);
513 }
514
UnRegisterDisplayListenerWithType(const std::string & type,int64_t funcId)515 DMError DisplayImpl::UnRegisterDisplayListenerWithType(const std::string& type, int64_t funcId)
516 {
517 TLOGD(WmsLogTag::DMS, "DisplayImpl::UnRegisterDisplayListenerWithType is called");
518 if (g_cjCbMap.empty() || g_cjCbMap.find(type) == g_cjCbMap.end()) {
519 TLOGI(WmsLogTag::DMS, "UnRegisterDisplayListenerWithType methodName %{public}s not registered", type.c_str());
520 return DMError::DM_OK;
521 }
522 DMError ret = DMError::DM_OK;
523 for (auto it = g_cjCbMap[type].begin(); it != g_cjCbMap[type].end();) {
524 if (it->first == funcId) {
525 it->second->RemoveAllCallback();
526 if (type == EVENT_AVAILABLE_AREA_CHANGED) {
527 sptr<DisplayManager::IAvailableAreaListener> thisListener(it->second);
528 ret = SingletonContainer::Get<DisplayManager>().UnregisterAvailableAreaListener(thisListener);
529 } else {
530 ret = DMError::DM_ERROR_INVALID_PARAM;
531 }
532 g_cjCbMap[type].erase(it++);
533 break;
534 } else {
535 it++;
536 }
537 }
538 if (g_cjCbMap[type].empty()) {
539 g_cjCbMap.erase(type);
540 }
541 return ret;
542 }
543 } // namespace Rosen
544 } // namespace OHOS
545