1 /*
2  * Copyright (c) 2021-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 
16 #include "abstract_display.h"
17 
18 #include "abstract_screen_controller.h"
19 #include "display_manager_config.h"
20 #include "display_manager_service.h"
21 #include "window_manager_hilog.h"
22 
23 namespace OHOS::Rosen {
24 namespace {
25 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "AbstractDisplay"};
26 constexpr int32_t PAD_SCREEN_WIDTH = 2560;
27 constexpr int32_t PHONE_SCREEN_WIDTH = 2160;
28 constexpr float INCH_2_MM = 25.4f;
29 }
30 
AbstractDisplay(DisplayId id,sptr<SupportedScreenModes> & info,sptr<AbstractScreen> & absScreen)31 AbstractDisplay::AbstractDisplay(DisplayId id, sptr<SupportedScreenModes>& info, sptr<AbstractScreen>& absScreen)
32     : id_(id)
33 {
34     if (info == nullptr || absScreen == nullptr) {
35         WLOGFE("info or absScreen is nullptr");
36         return;
37     }
38     screenId_ = absScreen->dmsId_;
39     screenGroupId_ = absScreen->groupDmsId_;
40     width_ = static_cast<int32_t>(info->width_);
41     height_ = static_cast<int32_t>(info->height_);
42     refreshRate_ = info->refreshRate_;
43     orientation_ = absScreen->orientation_;
44     name_ = absScreen->GetScreenName();
45     static_cast<void>(RequestRotation(absScreen->rotation_));
46     if (width_ > height_) {
47         displayOrientation_ = DisplayOrientation::LANDSCAPE;
48     } else {
49         displayOrientation_ = DisplayOrientation::PORTRAIT;
50     }
51     if (info->width_ < info->height_) {
52         isDefaultVertical_ = true;
53     } else {
54         isDefaultVertical_ = false;
55     }
56 
57     CalculateXYDpi(absScreen->GetPhyWidth(), absScreen->GetPhyHeight());
58     auto numbersConfig = DisplayManagerConfig::GetIntNumbersConfig();
59     if (numbersConfig.count("dpi") != 0) {
60         uint32_t densityDpi = static_cast<uint32_t>(numbersConfig["dpi"][0]);
61         if (densityDpi >= DOT_PER_INCH_MINIMUM_VALUE && densityDpi <= DOT_PER_INCH_MAXIMUM_VALUE) {
62             virtualPixelRatio_ = static_cast<float>(densityDpi) / BASELINE_DENSITY;
63             absScreen->SetVirtualPixelRatio(virtualPixelRatio_);
64             return;
65         }
66     }
67     if ((info->width_ >= PHONE_SCREEN_WIDTH) || (info->height_ >= PHONE_SCREEN_WIDTH)) {
68         if ((info->width_ == PAD_SCREEN_WIDTH) || (info->height_ == PAD_SCREEN_WIDTH)) {
69             virtualPixelRatio_ = 2.0f; // Pad is 2.0
70         } else {
71             virtualPixelRatio_ = 3.0f; // Phone is 3.0
72         }
73     } else {
74         virtualPixelRatio_ = 1.0f; // Other is 1.0
75     }
76     absScreen->SetVirtualPixelRatio(virtualPixelRatio_);
77 }
78 
CalculateXYDpi(uint32_t phyWidth,uint32_t phyHeight)79 void AbstractDisplay::CalculateXYDpi(uint32_t phyWidth, uint32_t phyHeight)
80 {
81     if (phyWidth == 0 || phyHeight == 0) {
82         return;
83     }
84 
85     phyWidth_ = phyWidth;
86     phyHeight_ = phyHeight;
87     xDpi_ = width_ * INCH_2_MM / phyWidth_;
88     yDpi_ = height_ * INCH_2_MM / phyHeight_;
89 }
90 
GetId() const91 DisplayId AbstractDisplay::GetId() const
92 {
93     return id_;
94 }
95 
GetWidth() const96 int32_t AbstractDisplay::GetWidth() const
97 {
98     return width_;
99 }
100 
GetHeight() const101 int32_t AbstractDisplay::GetHeight() const
102 {
103     return height_;
104 }
105 
GetRefreshRate() const106 uint32_t AbstractDisplay::GetRefreshRate() const
107 {
108     return refreshRate_;
109 }
110 
GetVirtualPixelRatio() const111 float AbstractDisplay::GetVirtualPixelRatio() const
112 {
113     return virtualPixelRatio_;
114 }
115 
GetOffsetX() const116 int32_t AbstractDisplay::GetOffsetX() const
117 {
118     return offsetX_;
119 }
120 
GetOffsetY() const121 int32_t AbstractDisplay::GetOffsetY() const
122 {
123     return offsetY_;
124 }
125 
SetOffsetX(int32_t offsetX)126 void AbstractDisplay::SetOffsetX(int32_t offsetX)
127 {
128     offsetX_ = offsetX;
129 }
130 
SetOffsetY(int32_t offsetY)131 void AbstractDisplay::SetOffsetY(int32_t offsetY)
132 {
133     offsetY_ = offsetY;
134 }
135 
SetWidth(int32_t width)136 void AbstractDisplay::SetWidth(int32_t width)
137 {
138     width_ = width;
139     UpdateXDpi();
140 }
141 
SetHeight(int32_t height)142 void AbstractDisplay::SetHeight(int32_t height)
143 {
144     height_ = height;
145     UpdateYDpi();
146 }
147 
UpdateXDpi()148 void AbstractDisplay::UpdateXDpi()
149 {
150     if (phyWidth_ != UINT32_MAX) {
151         xDpi_ = width_ * INCH_2_MM / phyWidth_;
152     }
153 }
154 
UpdateYDpi()155 void AbstractDisplay::UpdateYDpi()
156 {
157     if (phyHeight_ != UINT32_MAX) {
158         yDpi_ = height_ * INCH_2_MM / phyHeight_;
159     }
160 }
161 
SetOffset(int32_t offsetX,int32_t offsetY)162 void AbstractDisplay::SetOffset(int32_t offsetX, int32_t offsetY)
163 {
164     offsetX_ = offsetX;
165     offsetY_ = offsetY;
166 }
167 
SetRefreshRate(uint32_t refreshRate)168 void AbstractDisplay::SetRefreshRate(uint32_t refreshRate)
169 {
170     refreshRate_ = refreshRate;
171 }
172 
SetVirtualPixelRatio(float virtualPixelRatio)173 void AbstractDisplay::SetVirtualPixelRatio(float virtualPixelRatio)
174 {
175     virtualPixelRatio_ = virtualPixelRatio;
176 }
177 
SetId(DisplayId id)178 void AbstractDisplay::SetId(DisplayId id)
179 {
180     id_ = id;
181 }
182 
SetOrientation(Orientation orientation)183 void AbstractDisplay::SetOrientation(Orientation orientation)
184 {
185     orientation_ = orientation;
186 }
187 
SetDisplayOrientation(DisplayOrientation displayOrientation)188 void AbstractDisplay::SetDisplayOrientation(DisplayOrientation displayOrientation)
189 {
190     displayOrientation_ = displayOrientation;
191 }
192 
RequestRotation(Rotation rotation)193 bool AbstractDisplay::RequestRotation(Rotation rotation)
194 {
195     WLOGD("request rotation from %{public}u to %{public}u, display %{public}" PRIu64"", rotation_, rotation, id_);
196     if (rotation_ == rotation) {
197         WLOGFE("rotation not change %{public}u", rotation);
198         return false;
199     }
200     if (IsVertical(rotation) != IsVertical(rotation_)) {
201         std::swap(width_, height_);
202     }
203     rotation_ = rotation;
204     return true;
205 }
206 
GetRotation() const207 Rotation AbstractDisplay::GetRotation() const
208 {
209     return rotation_;
210 }
211 
GetOrientation() const212 Orientation AbstractDisplay::GetOrientation() const
213 {
214     return orientation_;
215 }
216 
GetDisplayOrientation() const217 DisplayOrientation AbstractDisplay::GetDisplayOrientation() const
218 {
219     return displayOrientation_;
220 }
221 
SetFreezeFlag(FreezeFlag freezeFlag)222 void AbstractDisplay::SetFreezeFlag(FreezeFlag freezeFlag)
223 {
224     freezeFlag_ = freezeFlag;
225 }
226 
GetFreezeFlag() const227 FreezeFlag AbstractDisplay::GetFreezeFlag() const
228 {
229     return freezeFlag_;
230 }
231 
BindAbstractScreen(sptr<AbstractScreen> abstractScreen)232 bool AbstractDisplay::BindAbstractScreen(sptr<AbstractScreen> abstractScreen)
233 {
234     if (abstractScreen == nullptr) {
235         WLOGE("display bind screen error, cannot get screen. display:%{public}" PRIu64"", id_);
236         return false;
237     }
238     ScreenId dmsScreenId = abstractScreen->dmsId_;
239     sptr<SupportedScreenModes> info = abstractScreen->GetActiveScreenMode();
240     if (info == nullptr) {
241         WLOGE("display bind screen error, cannot get info. display:%{public}" PRIu64", screen:%{public}" PRIu64"",
242             id_, dmsScreenId);
243         return false;
244     }
245 
246     Point point = abstractScreen->GetGroup()->GetChildPosition(dmsScreenId);
247     offsetX_ = point.posX_;
248     offsetY_ = point.posY_;
249     width_ = static_cast<int32_t>(info->width_);
250     height_ = static_cast<int32_t>(info->height_);
251     refreshRate_ = info->refreshRate_;
252     screenId_ = dmsScreenId;
253     WLOGD("display bind to screen. display:%{public}" PRIu64", screen:%{public}" PRIu64"", id_, dmsScreenId);
254     return true;
255 }
256 
GetAbstractScreenId() const257 ScreenId AbstractDisplay::GetAbstractScreenId() const
258 {
259     return screenId_;
260 }
261 
GetAbstractScreenGroupId() const262 ScreenId AbstractDisplay::GetAbstractScreenGroupId() const
263 {
264     return screenGroupId_;
265 }
266 
ConvertToDisplayInfo() const267 sptr<DisplayInfo> AbstractDisplay::ConvertToDisplayInfo() const
268 {
269     sptr<DisplayInfo> displayInfo = new(std::nothrow) DisplayInfo();
270     if (displayInfo == nullptr) {
271         return displayInfo;
272     }
273 
274     displayInfo->name_ = name_;
275     displayInfo->SetDisplayId(id_);
276     displayInfo->SetWidth(width_);
277     displayInfo->SetHeight(height_);
278     displayInfo->SetRefreshRate(refreshRate_);
279     displayInfo->SetScreenId(screenId_);
280     displayInfo->SetScreenGroupId(screenGroupId_);
281     displayInfo->SetVirtualPixelRatio(virtualPixelRatio_);
282     displayInfo->SetXDpi(xDpi_);
283     displayInfo->SetYDpi(yDpi_);
284     displayInfo->SetDpi(virtualPixelRatio_ * DOT_PER_INCH);
285     displayInfo->SetRotation(rotation_);
286     displayInfo->SetOrientation(orientation_);
287     displayInfo->SetOffsetX(offsetX_);
288     displayInfo->SetOffsetY(offsetY_);
289     displayInfo->displayState_ = displayState_;
290     displayInfo->SetWaterfallDisplayCompressionStatus(waterfallDisplayCompressionStatus_);
291     displayInfo->SetDisplayOrientation(displayOrientation_);
292     displayInfo->SetIsDefaultVertical(isDefaultVertical_);
293     return displayInfo;
294 }
295 } // namespace OHOS::Rosen