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 #include <map>
18 #include <securec.h>
19 #include "cutout_info.h"
20 #include "display.h"
21 #include "display_info.h"
22 #include "window_manager_hilog.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 const std::map<DisplayState,      DisplayStateMode> NATIVE_TO_CJ_DISPLAY_STATE_MAP {
28     { DisplayState::UNKNOWN,      DisplayStateMode::STATE_UNKNOWN      },
29     { DisplayState::OFF,          DisplayStateMode::STATE_OFF          },
30     { DisplayState::ON,           DisplayStateMode::STATE_ON           },
31     { DisplayState::DOZE,         DisplayStateMode::STATE_DOZE         },
32     { DisplayState::DOZE_SUSPEND, DisplayStateMode::STATE_DOZE_SUSPEND },
33     { DisplayState::VR,           DisplayStateMode::STATE_VR           },
34     { DisplayState::ON_SUSPEND,   DisplayStateMode::STATE_ON_SUSPEND   },
35 };
36 }
37 static thread_local std::map<uint64_t, sptr<DisplayImpl>> g_cjDisplayMap;
38 std::recursive_mutex g_mutex;
39 
SetCRect(const DMRect & row,CRect * ptr)40 void SetCRect(const DMRect &row, CRect *ptr)
41 {
42     ptr->left = row.posX_;
43     ptr->top = row.posY_;
44     ptr->width = row.width_;
45     ptr->height = row.height_;
46 }
47 
CreateCBoundingRects(std::vector<DMRect> & bound)48 CRect* CreateCBoundingRects(std::vector<DMRect> &bound)
49 {
50     int32_t number = static_cast<int32_t>(bound.size());
51     CRect *result = static_cast<CRect*>(malloc(sizeof(CRect) * number));
52     if (result == nullptr) {
53         TLOGE(WmsLogTag::DMS, "[CreateCBoundingRects] memory failed.");
54         return nullptr;
55     }
56     for (int i = 0; i < number; i++) {
57         SetCRect(bound[i], (result + i));
58     }
59     return result;
60 }
61 
SetCWaterfallDisplayAreaRects(const WaterfallDisplayAreaRects & area,CCutoutInfo * info)62 void SetCWaterfallDisplayAreaRects(const WaterfallDisplayAreaRects &area, CCutoutInfo * info)
63 {
64     if (info == nullptr || info->boundingRects == nullptr) {
65         return;
66     }
67     SetCRect(area.left, &(info->waterfallDisplayAreaRects.left));
68     SetCRect(area.top, &(info->waterfallDisplayAreaRects.top));
69     SetCRect(area.right, &(info->waterfallDisplayAreaRects.right));
70     SetCRect(area.bottom, &(info->waterfallDisplayAreaRects.bottom));
71 }
72 
CreateCCutoutInfoObject(sptr<CutoutInfo> & cutoutInfo)73 CCutoutInfo* CreateCCutoutInfoObject(sptr<CutoutInfo> &cutoutInfo)
74 {
75     CCutoutInfo *info = static_cast<CCutoutInfo*>(malloc(sizeof(CCutoutInfo)));
76     if (info == nullptr) {
77         return nullptr;
78     }
79     std::vector<DMRect> boundingRects = cutoutInfo->GetBoundingRects();
80     WaterfallDisplayAreaRects waterfallDisplayAreaRects = cutoutInfo->GetWaterfallDisplayAreaRects();
81     info->number = static_cast<int64_t>(boundingRects.size());
82     info->boundingRects = CreateCBoundingRects(boundingRects);
83     if (info->boundingRects == nullptr) {
84         TLOGE(WmsLogTag::DMS, "[CreateCCutoutInfoObject] memory failed.");
85         free(info);
86         return nullptr;
87     }
88     SetCWaterfallDisplayAreaRects(waterfallDisplayAreaRects, info);
89     return info;
90 }
91 
FindDisplayObject(uint64_t displayId)92 sptr<DisplayImpl> DisplayImpl::FindDisplayObject(uint64_t displayId)
93 {
94     std::lock_guard<std::recursive_mutex> lock(g_mutex);
95     if (g_cjDisplayMap.find(displayId) == g_cjDisplayMap.end()) {
96         TLOGI(WmsLogTag::DMS,
97             "[FindDisplayObject] Can not find display %{public}" PRIu64" in display map", displayId);
98         return nullptr;
99     }
100     return g_cjDisplayMap[displayId];
101 }
102 
DisplayImpl(const sptr<Display> & display)103 DisplayImpl::DisplayImpl(const sptr<Display>& display) : display_(display)
104 {}
105 
~DisplayImpl()106 DisplayImpl::~DisplayImpl()
107 {
108     uint64_t displayId = display_->GetId();
109     sptr<DisplayImpl> cjDisplayPtr = DisplayImpl::FindDisplayObject(displayId);
110     if (cjDisplayPtr == nullptr) {
111         return;
112     }
113     std::lock_guard<std::recursive_mutex> lock(g_mutex);
114     g_cjDisplayMap.erase(displayId);
115     return;
116 }
117 
CreateDisplayImpl(sptr<Display> & display)118 sptr<DisplayImpl> DisplayImpl::CreateDisplayImpl(sptr<Display> &display)
119 {
120     uint64_t displayId = display->GetId();
121     sptr<DisplayImpl> cjDisplayPtr = DisplayImpl::FindDisplayObject(displayId);
122     auto info = display->GetDisplayInfo();
123     if (info == nullptr) {
124         TLOGE(WmsLogTag::DMS, "[CreateDisplayImpl] Failed to get display info");
125         return nullptr;
126     }
127     if (cjDisplayPtr == nullptr) {
128         cjDisplayPtr = FFIData::Create<DisplayImpl>(display);
129         if (cjDisplayPtr == nullptr) {
130             TLOGE(WmsLogTag::DMS, "[CreateDisplayImpl] Failed to create display");
131             return nullptr;
132         }
133         std::lock_guard<std::recursive_mutex> lock(g_mutex);
134         g_cjDisplayMap[displayId] = cjDisplayPtr;
135     }
136     return cjDisplayPtr;
137 }
138 
GetInfoId()139 uint32_t DisplayImpl::GetInfoId()
140 {
141     auto info = display_->GetDisplayInfo();
142     if (info == nullptr) {
143         TLOGE(WmsLogTag::DMS, "[GetInfoId] Failed to get display info");
144         return static_cast<uint32_t>(DISPLAY_ID_INVALID);
145     }
146     return static_cast<uint32_t>(info->GetDisplayId());
147 }
148 
GetName()149 char* DisplayImpl::GetName()
150 {
151     auto info = display_->GetDisplayInfo();
152     if (info == nullptr) {
153         TLOGE(WmsLogTag::DMS, "[GetName] Failed to get display info");
154         return nullptr;
155     }
156     auto name = info->GetName();
157     int len = static_cast<int>(name.length());
158     char *retData = static_cast<char*>(malloc(len + 1));
159     if (retData == nullptr) {
160         return nullptr;
161     }
162     int ret = memcpy_s(retData, len + 1, name.c_str(), len + 1);
163     if (ret != 0) {
164         TLOGE(WmsLogTag::DMS, "[DisplayImpl] Failed to get name");
165         free(retData);
166         retData = nullptr;
167     }
168     return retData;
169 }
170 
GetAlive()171 bool DisplayImpl::GetAlive()
172 {
173     auto info = display_->GetDisplayInfo();
174     if (info == nullptr) {
175         TLOGE(WmsLogTag::DMS, "[GetAlive] Failed to get display info");
176         return false;
177     }
178     return info->GetAliveStatus();
179 }
180 
GetState()181 uint32_t DisplayImpl::GetState()
182 {
183     auto info = display_->GetDisplayInfo();
184     if (info == nullptr) {
185         TLOGE(WmsLogTag::DMS, "[GetState] Failed to get display info");
186         return static_cast<uint32_t>(DisplayStateMode::STATE_UNKNOWN);
187     }
188     auto state = info->GetDisplayState();
189     if (NATIVE_TO_CJ_DISPLAY_STATE_MAP.count(state) != 0) {
190         return static_cast<uint32_t>(NATIVE_TO_CJ_DISPLAY_STATE_MAP.at(state));
191     } else {
192         return static_cast<uint32_t>(DisplayStateMode::STATE_UNKNOWN);
193     }
194 }
195 
GetRefreshRate()196 uint32_t DisplayImpl::GetRefreshRate()
197 {
198     auto info = display_->GetDisplayInfo();
199     if (info == nullptr) {
200         TLOGE(WmsLogTag::DMS, "[GetRefreshRate] Failed to get display info");
201         return 0;
202     }
203     return info->GetRefreshRate();
204 }
205 
GetRotation()206 uint32_t DisplayImpl::GetRotation()
207 {
208     auto info = display_->GetDisplayInfo();
209     if (info == nullptr) {
210         TLOGE(WmsLogTag::DMS, "[GetRotation] Failed to get display info");
211         return 0;
212     }
213     return static_cast<uint32_t>(info->GetRotation());
214 }
215 
GetOrientation()216 uint32_t DisplayImpl::GetOrientation()
217 {
218     auto info = display_->GetDisplayInfo();
219     if (info == nullptr) {
220         TLOGE(WmsLogTag::DMS, "[GetOrientation] Failed to get display info");
221         return 0;
222     }
223     return static_cast<uint32_t>(info->GetDisplayOrientation());
224 }
225 
GetWidth()226 int32_t DisplayImpl::GetWidth()
227 {
228     auto info = display_->GetDisplayInfo();
229     if (info == nullptr) {
230         TLOGE(WmsLogTag::DMS, "[GetWidth] Failed to get display info");
231         return 0;
232     }
233     return info->GetWidth();
234 }
235 
GetHeight()236 int32_t DisplayImpl::GetHeight()
237 {
238     auto info = display_->GetDisplayInfo();
239     if (info == nullptr) {
240         TLOGE(WmsLogTag::DMS, "[GetHeight] Failed to get display info");
241         return 0;
242     }
243     return info->GetHeight();
244 }
245 
GetDensityDPI()246 float DisplayImpl::GetDensityDPI()
247 {
248     auto info = display_->GetDisplayInfo();
249     if (info == nullptr) {
250         TLOGE(WmsLogTag::DMS, "[GetDensityDPI] Failed to get display info");
251         return 1.0 * DOT_PER_INCH;
252     }
253     return info->GetVirtualPixelRatio() * DOT_PER_INCH;
254 }
255 
GetVirtualPixelRatio()256 float DisplayImpl::GetVirtualPixelRatio()
257 {
258     auto info = display_->GetDisplayInfo();
259     if (info == nullptr) {
260         TLOGE(WmsLogTag::DMS, "[GetVirtualPixelRatio] Failed to get display info");
261         return 1.0;
262     }
263     return info->GetVirtualPixelRatio();
264 }
265 
GetXDPI()266 float DisplayImpl::GetXDPI()
267 {
268     auto info = display_->GetDisplayInfo();
269     if (info == nullptr) {
270         TLOGE(WmsLogTag::DMS, "[GetXDPI] Failed to get display info");
271         return 0.0;
272     }
273     return info->GetXDpi();
274 }
275 
GetYDPI()276 float DisplayImpl::GetYDPI()
277 {
278     auto info = display_->GetDisplayInfo();
279     if (info == nullptr) {
280         TLOGE(WmsLogTag::DMS, "[GetYDPI] Failed to get display info");
281         return 0.0;
282     }
283     return info->GetYDpi();
284 }
285 
GetCutoutInfo()286 RetStruct DisplayImpl::GetCutoutInfo()
287 {
288     RetStruct result = {.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL), .len = 0, .data = nullptr};
289     sptr<CutoutInfo> cutoutInfo = display_->GetCutoutInfo();
290     if (cutoutInfo == nullptr) {
291         result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_INVALID_SCREEN);
292         return result;
293     }
294     result.data = CreateCCutoutInfoObject(cutoutInfo);
295     result.code = static_cast<int32_t>(DmErrorCode::DM_OK);
296     if (result.data == nullptr) {
297         result.code = static_cast<int32_t>(DmErrorCode::DM_ERROR_SYSTEM_INNORMAL);
298     }
299     return result;
300 }
301 }
302 }
303