1 /*
2  * Copyright (c) 2022 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 #include "display_manager_adapter_impl.h"
16 
17 #include <cmath>
18 #include "display_info.h"
19 #include "nweb_log.h"
20 #include "syspara/parameters.h"
21 #include "oh_display_manager.h"
22 #include "oh_display_info.h"
23 
24 using namespace OHOS::Rosen;
25 using namespace OHOS::NWeb;
26 
27 namespace OHOS::NWeb {
28 constexpr float EPS = 0.0001f;
29 
DisplayListenerAdapterImpl(std::shared_ptr<DisplayListenerAdapter> listener)30 DisplayListenerAdapterImpl::DisplayListenerAdapterImpl(
31     std::shared_ptr<DisplayListenerAdapter> listener) : listener_(listener) {}
32 
OnCreate(DisplayId id)33 void DisplayListenerAdapterImpl::OnCreate(DisplayId id)
34 {
35     if (listener_ != nullptr) {
36         listener_->OnCreate(id);
37     }
38 }
39 
OnDestroy(DisplayId id)40 void DisplayListenerAdapterImpl::OnDestroy(DisplayId id)
41 {
42     if (listener_ != nullptr) {
43         listener_->OnDestroy(id);
44     }
45 }
46 
OnChange(DisplayId id)47 void DisplayListenerAdapterImpl::OnChange(DisplayId id)
48 {
49     if (CheckOnlyRefreshRateDecreased(id)) {
50         return;
51     }
52     if (listener_ != nullptr) {
53         listener_->OnChange(id);
54     }
55 }
56 
CheckOnlyRefreshRateDecreased(DisplayId id)57 bool DisplayListenerAdapterImpl::CheckOnlyRefreshRateDecreased(DisplayId id)
58 {
59     if (id != DisplayManager::GetInstance().GetDefaultDisplayId()) {
60         return false;
61     }
62     auto displayPtr = DisplayManager::GetInstance().GetDefaultDisplay();
63     if (!displayPtr) {
64         return false;
65     }
66     auto displayInfo = displayPtr->GetDisplayInfo();
67     if (!displayInfo) {
68         return false;
69     }
70     auto nwebDisplayInfo =  ConvertDisplayInfo(*displayInfo);
71     if (nwebDisplayInfo == cachedDisplayedInfo_ &&
72         nwebDisplayInfo.refreshRate_ != cachedDisplayedInfo_.refreshRate_) {
73         WVLOG_D("refresh rate change is intercepted, previous refresh rate: %{public}u, after: %{public}u",
74             cachedDisplayedInfo_.refreshRate_, nwebDisplayInfo.refreshRate_);
75         cachedDisplayedInfo_ = nwebDisplayInfo;
76         return true;
77     }
78     cachedDisplayedInfo_ = nwebDisplayInfo;
79     return false;
80 }
81 
ConvertDisplayInfo(const OHOS::Rosen::DisplayInfo & info)82 OHOS::NWeb::DisplayInfo DisplayListenerAdapterImpl::ConvertDisplayInfo(
83     const OHOS::Rosen::DisplayInfo& info)
84 {
85     OHOS::NWeb::DisplayInfo displayInfo = OHOS::NWeb::DisplayInfo{};
86     displayInfo.width_ = info.GetWidth();
87     displayInfo.height_ = info.GetHeight();
88     displayInfo.refreshRate_ = info.GetRefreshRate();
89     displayInfo.virtualPixelRatio_ = info.GetVirtualPixelRatio();
90     displayInfo.xDpi_ = info.GetXDpi();
91     displayInfo.yDpi_ = info.GetYDpi();
92     displayInfo.rotationType_ = info.GetRotation();
93     displayInfo.orientationType_ = info.GetOrientation();
94     displayInfo.displayOrientation_ = info.GetDisplayOrientation();
95     return displayInfo;
96 }
97 
FoldStatusListenerAdapterImpl(std::shared_ptr<FoldStatusListenerAdapter> listener)98 FoldStatusListenerAdapterImpl::FoldStatusListenerAdapterImpl(
99     std::shared_ptr<FoldStatusListenerAdapter> listener) : listener_(listener) {}
100 
ConvertFoldStatus(NativeDisplayManager_FoldDisplayMode displayMode)101 OHOS::NWeb::FoldStatus FoldStatusListenerAdapterImpl::ConvertFoldStatus(
102     NativeDisplayManager_FoldDisplayMode displayMode)
103 {
104     switch (displayMode) {
105         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_FULL:
106             return OHOS::NWeb::FoldStatus::FULL;
107         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_MAIN:
108             return OHOS::NWeb::FoldStatus::MAIN;
109         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_SUB:
110             return OHOS::NWeb::FoldStatus::SUB;
111         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_COORDINATION:
112             return OHOS::NWeb::FoldStatus::COORDINATION;
113         default:
114             return OHOS::NWeb::FoldStatus::UNKNOWN;
115     }
116 }
117 
OnFoldStatusChanged(NativeDisplayManager_FoldDisplayMode displayMode)118 void FoldStatusListenerAdapterImpl::OnFoldStatusChanged(NativeDisplayManager_FoldDisplayMode displayMode)
119 {
120     if (listener_ != nullptr) {
121         listener_->OnFoldStatusChanged(ConvertFoldStatus(displayMode));
122     }
123 }
124 
DisplayAdapterImpl(sptr<OHOS::Rosen::Display> display)125 DisplayAdapterImpl::DisplayAdapterImpl(sptr<OHOS::Rosen::Display> display)
126     : display_(display) {}
127 
ConvertRotationType(OHOS::Rosen::Rotation type)128 OHOS::NWeb::RotationType DisplayAdapterImpl::ConvertRotationType(OHOS::Rosen::Rotation type)
129 {
130     switch (type) {
131         case OHOS::Rosen::Rotation::ROTATION_0:
132             return OHOS::NWeb::RotationType::ROTATION_0;
133         case OHOS::Rosen::Rotation::ROTATION_90:
134             return OHOS::NWeb::RotationType::ROTATION_90;
135         case OHOS::Rosen::Rotation::ROTATION_180:
136             return OHOS::NWeb::RotationType::ROTATION_180;
137         case OHOS::Rosen::Rotation::ROTATION_270:
138             return OHOS::NWeb::RotationType::ROTATION_270;
139         default:
140             return OHOS::NWeb::RotationType::ROTATION_BUTT;
141     }
142 }
143 
ConvertOrientationType(OHOS::Rosen::Orientation type)144 OHOS::NWeb::OrientationType DisplayAdapterImpl::ConvertOrientationType(OHOS::Rosen::Orientation type)
145 {
146     switch (type) {
147         case OHOS::Rosen::Orientation::UNSPECIFIED:
148             return OHOS::NWeb::OrientationType::UNSPECIFIED;
149         case OHOS::Rosen::Orientation::VERTICAL:
150             return OHOS::NWeb::OrientationType::VERTICAL;
151         case OHOS::Rosen::Orientation::HORIZONTAL:
152             return OHOS::NWeb::OrientationType::HORIZONTAL;
153         case OHOS::Rosen::Orientation::REVERSE_VERTICAL:
154             return OHOS::NWeb::OrientationType::REVERSE_VERTICAL;
155         case OHOS::Rosen::Orientation::REVERSE_HORIZONTAL:
156             return OHOS::NWeb::OrientationType::REVERSE_HORIZONTAL;
157         case OHOS::Rosen::Orientation::SENSOR:
158             return OHOS::NWeb::OrientationType::SENSOR;
159         case OHOS::Rosen::Orientation::SENSOR_VERTICAL:
160             return OHOS::NWeb::OrientationType::SENSOR_VERTICAL;
161         case OHOS::Rosen::Orientation::SENSOR_HORIZONTAL:
162             return OHOS::NWeb::OrientationType::SENSOR_HORIZONTAL;
163         default:
164             return OHOS::NWeb::OrientationType::BUTT;
165     }
166 }
167 
ConvertDisplayOrientationType(OHOS::Rosen::DisplayOrientation type)168 OHOS::NWeb::DisplayOrientation DisplayAdapterImpl::ConvertDisplayOrientationType(OHOS::Rosen::DisplayOrientation type)
169 {
170     switch (type) {
171         case OHOS::Rosen::DisplayOrientation::PORTRAIT:
172             return OHOS::NWeb::DisplayOrientation::PORTRAIT;
173         case OHOS::Rosen::DisplayOrientation::LANDSCAPE:
174             return OHOS::NWeb::DisplayOrientation::LANDSCAPE;
175         case OHOS::Rosen::DisplayOrientation::PORTRAIT_INVERTED:
176             return OHOS::NWeb::DisplayOrientation::PORTRAIT_INVERTED;
177         case OHOS::Rosen::DisplayOrientation::LANDSCAPE_INVERTED:
178             return OHOS::NWeb::DisplayOrientation::LANDSCAPE_INVERTED;
179         default:
180             return OHOS::NWeb::DisplayOrientation::UNKNOWN;
181     }
182 }
183 
184 
ConvertFoldStatus(NativeDisplayManager_FoldDisplayMode displayMode)185 OHOS::NWeb::FoldStatus DisplayAdapterImpl::ConvertFoldStatus(NativeDisplayManager_FoldDisplayMode displayMode)
186 {
187     switch (displayMode) {
188         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_FULL:
189             return OHOS::NWeb::FoldStatus::FULL;
190         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_MAIN:
191             return OHOS::NWeb::FoldStatus::MAIN;
192         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_SUB:
193             return OHOS::NWeb::FoldStatus::SUB;
194         case DISPLAY_MANAGER_FOLD_DISPLAY_MODE_COORDINATION:
195             return OHOS::NWeb::FoldStatus::COORDINATION;
196         default:
197             return OHOS::NWeb::FoldStatus::UNKNOWN;
198     }
199 }
200 
GetId()201 DisplayId DisplayAdapterImpl::GetId()
202 {
203     if (display_ != nullptr) {
204         return display_->GetId();
205     }
206     return static_cast<DisplayId>(-1);
207 }
208 
GetWidth()209 int32_t DisplayAdapterImpl::GetWidth()
210 {
211     if (display_ != nullptr) {
212         return display_->GetWidth();
213     }
214     return -1;
215 }
216 
GetHeight()217 int32_t DisplayAdapterImpl::GetHeight()
218 {
219     if (display_ != nullptr) {
220         return display_->GetHeight();
221     }
222     return -1;
223 }
224 
GetVirtualPixelRatio()225 float DisplayAdapterImpl::GetVirtualPixelRatio()
226 {
227     if (display_ != nullptr) {
228         return display_->GetVirtualPixelRatio();
229     }
230     return -1;
231 }
232 
GetRotation()233 RotationType DisplayAdapterImpl::GetRotation()
234 {
235     if (display_ != nullptr) {
236         return ConvertRotationType(display_->GetRotation());
237     }
238     return RotationType::ROTATION_BUTT;
239 }
240 
GetOrientation()241 OrientationType DisplayAdapterImpl::GetOrientation()
242 {
243     if (display_ != nullptr) {
244         return ConvertOrientationType(display_->GetOrientation());
245     }
246     return OrientationType::BUTT;
247 }
248 
GetDpi()249 int32_t DisplayAdapterImpl::GetDpi()
250 {
251     int32_t ppi = -1;
252     if (!display_) {
253         return ppi;
254     }
255     auto displayInfo = display_->GetDisplayInfo();
256     if (!displayInfo) {
257         return ppi;
258     }
259     float xDpi = displayInfo->GetXDpi();
260     float yDpi = displayInfo->GetYDpi();
261     if (xDpi < EPS || yDpi < EPS) {
262         return ppi;
263     }
264 
265     auto screenLength = sqrt(pow(displayInfo->GetWidth(), 2) + pow(displayInfo->GetHeight(), 2));
266     auto phyScreenLength = sqrt(pow(displayInfo->GetWidth() / xDpi, 2) +
267         pow(displayInfo->GetHeight() / yDpi, 2));
268     if (phyScreenLength < EPS) {
269         return ppi;
270     }
271     ppi = screenLength / phyScreenLength;
272     WVLOG_D("dpi: %{public}d, xdpi: %{public}f,ydpi: %{public}f, width: %{public}d, height: %{public}d, "\
273         "phyScreenLength: %{public}f", ppi, displayInfo->GetXDpi(), displayInfo->GetYDpi(),
274         displayInfo->GetWidth(), displayInfo->GetHeight(), phyScreenLength);
275 
276     return ppi;
277 }
278 
GetDisplayOrientation()279 DisplayOrientation DisplayAdapterImpl::GetDisplayOrientation()
280 {
281     if (display_ != nullptr) {
282         auto displayInfo = display_->GetDisplayInfo();
283         if (displayInfo != nullptr) {
284             return ConvertDisplayOrientationType(displayInfo->GetDisplayOrientation());
285         }
286     }
287     return DisplayOrientation::UNKNOWN;
288 }
289 
GetFoldStatus()290 FoldStatus DisplayAdapterImpl::GetFoldStatus()
291 {
292     NativeDisplayManager_FoldDisplayMode displayMode =
293         NativeDisplayManager_FoldDisplayMode::DISPLAY_MANAGER_FOLD_DISPLAY_MODE_UNKNOWN;
294     OH_NativeDisplayManager_GetFoldDisplayMode(&displayMode);
295     return ConvertFoldStatus(displayMode);
296 }
297 
IsFoldable()298 bool DisplayAdapterImpl::IsFoldable()
299 {
300     return OH_NativeDisplayManager_IsFoldable();
301 }
302 
GetDefaultDisplayId()303 DisplayId DisplayManagerAdapterImpl::GetDefaultDisplayId()
304 {
305     return DisplayManager::GetInstance().GetDefaultDisplayId();
306 }
307 
GetDefaultDisplay()308 std::shared_ptr<DisplayAdapter> DisplayManagerAdapterImpl::GetDefaultDisplay()
309 {
310     sptr<Display> display = DisplayManager::GetInstance().GetDefaultDisplay();
311     return std::make_shared<DisplayAdapterImpl>(display);
312 }
313 
RegisterDisplayListener(std::shared_ptr<DisplayListenerAdapter> listener)314 uint32_t DisplayManagerAdapterImpl::RegisterDisplayListener(
315     std::shared_ptr<DisplayListenerAdapter> listener)
316 {
317     static uint32_t count = 1;
318     sptr<DisplayListenerAdapterImpl> reg =
319         new (std::nothrow) DisplayListenerAdapterImpl(listener);
320     if (reg == nullptr) {
321         return false;
322     }
323 
324     uint32_t id = count++;
325     if (count == 0) {
326         count++;
327     }
328 
329     reg_.emplace(std::make_pair(id, reg));
330     if (DisplayManager::GetInstance().RegisterDisplayListener(reg) == DMError::DM_OK) {
331         return id;
332     } else {
333         return 0;
334     }
335 }
336 
UnregisterDisplayListener(uint32_t id)337 bool DisplayManagerAdapterImpl::UnregisterDisplayListener(uint32_t id)
338 {
339     ListenerMap::iterator iter = reg_.find(id);
340     if (iter == reg_.end()) {
341         return false;
342     }
343     if (DisplayManager::GetInstance().UnregisterDisplayListener(iter->second) == DMError::DM_OK) {
344         reg_.erase(iter);
345         return true;
346     }
347     return false;
348 }
349 
IsDefaultPortrait()350 bool DisplayManagerAdapterImpl::IsDefaultPortrait()
351 {
352     std::string deviceType = OHOS::system::GetDeviceType();
353     return deviceType == "phone" || deviceType == "default";
354 }
355 
356 FoldStatusListenerMap DisplayManagerAdapterImpl::foldStatusReg_;
357 
FoldChangeCallBack(NativeDisplayManager_FoldDisplayMode displayMode)358 void FoldChangeCallBack(NativeDisplayManager_FoldDisplayMode displayMode)
359 {
360     for (auto& iter : DisplayManagerAdapterImpl::foldStatusReg_) {
361         iter.second->OnFoldStatusChanged(displayMode);
362     }
363 }
364 
RegisterFoldStatusListener(std::shared_ptr<FoldStatusListenerAdapter> listener)365 uint32_t DisplayManagerAdapterImpl::RegisterFoldStatusListener(
366     std::shared_ptr<FoldStatusListenerAdapter> listener)
367 {
368     sptr<FoldStatusListenerAdapterImpl> reg =
369         new (std::nothrow) FoldStatusListenerAdapterImpl(listener);
370     if (reg == nullptr) {
371         return false;
372     }
373 
374     uint32_t id = 1;
375     if (OH_NativeDisplayManager_RegisterFoldDisplayModeChangeListener(
376         FoldChangeCallBack, &id) == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
377         foldStatusReg_.emplace(std::make_pair(id, reg));
378         return id;
379     } else {
380         return 0;
381     }
382 }
383 
UnregisterFoldStatusListener(uint32_t id)384 bool DisplayManagerAdapterImpl::UnregisterFoldStatusListener(uint32_t id)
385 {
386     FoldStatusListenerMap::iterator iter = foldStatusReg_.find(id);
387     if (iter == foldStatusReg_.end()) {
388         return false;
389     }
390     if (OH_NativeDisplayManager_UnregisterFoldDisplayModeChangeListener(id) ==
391         NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) {
392         foldStatusReg_.erase(iter);
393         return true;
394     }
395     return false;
396 }
397 }
398