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 int32_t PAD_SCREEN_WIDTH = 2560;
26 constexpr int32_t PHONE_SCREEN_WIDTH = 2160;
27 constexpr float INCH_2_MM = 25.4f;
28 constexpr ScreenId DEFAULT_DISPLAY_ID = 0;
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 TLOGE(WmsLogTag::DMS, "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 TLOGD(WmsLogTag::DMS, "request rotation from %{public}u to %{public}u, display %{public}" PRIu64"", rotation_,
196 rotation, id_);
197 if (rotation_ == rotation) {
198 TLOGE(WmsLogTag::DMS, "rotation not change %{public}u", rotation);
199 return false;
200 }
201 if (IsVertical(rotation) != IsVertical(rotation_)) {
202 std::swap(width_, height_);
203 }
204 rotation_ = rotation;
205 return true;
206 }
207
GetRotation() const208 Rotation AbstractDisplay::GetRotation() const
209 {
210 return rotation_;
211 }
212
GetOrientation() const213 Orientation AbstractDisplay::GetOrientation() const
214 {
215 return orientation_;
216 }
217
GetDisplayOrientation() const218 DisplayOrientation AbstractDisplay::GetDisplayOrientation() const
219 {
220 return displayOrientation_;
221 }
222
SetFreezeFlag(FreezeFlag freezeFlag)223 void AbstractDisplay::SetFreezeFlag(FreezeFlag freezeFlag)
224 {
225 freezeFlag_ = freezeFlag;
226 }
227
GetFreezeFlag() const228 FreezeFlag AbstractDisplay::GetFreezeFlag() const
229 {
230 return freezeFlag_;
231 }
232
BindAbstractScreen(sptr<AbstractScreen> abstractScreen)233 bool AbstractDisplay::BindAbstractScreen(sptr<AbstractScreen> abstractScreen)
234 {
235 if (abstractScreen == nullptr) {
236 TLOGE(WmsLogTag::DMS, "display bind screen error, cannot get screen. display:%{public}" PRIu64"", id_);
237 return false;
238 }
239 ScreenId dmsScreenId = abstractScreen->dmsId_;
240 sptr<SupportedScreenModes> info = abstractScreen->GetActiveScreenMode();
241 if (info == nullptr) {
242 TLOGE(WmsLogTag::DMS, "display bind screen error, cannot get info. display:%{public}" PRIu64", "
243 "screen:%{public}" PRIu64"", id_, dmsScreenId);
244 return false;
245 }
246
247 Point point = abstractScreen->GetGroup()->GetChildPosition(dmsScreenId);
248 offsetX_ = point.posX_;
249 offsetY_ = point.posY_;
250 width_ = static_cast<int32_t>(info->width_);
251 height_ = static_cast<int32_t>(info->height_);
252 refreshRate_ = info->refreshRate_;
253 screenId_ = dmsScreenId;
254 TLOGD(WmsLogTag::DMS, "display bind to screen. display:%{public}" PRIu64", screen:%{public}" PRIu64"", id_,
255 dmsScreenId);
256 return true;
257 }
258
GetAbstractScreenId() const259 ScreenId AbstractDisplay::GetAbstractScreenId() const
260 {
261 return screenId_;
262 }
263
GetAbstractScreenGroupId() const264 ScreenId AbstractDisplay::GetAbstractScreenGroupId() const
265 {
266 return screenGroupId_;
267 }
268
ConvertToDisplayInfo() const269 sptr<DisplayInfo> AbstractDisplay::ConvertToDisplayInfo() const
270 {
271 sptr<DisplayInfo> displayInfo = new(std::nothrow) DisplayInfo();
272 if (displayInfo == nullptr) {
273 return displayInfo;
274 }
275
276 displayInfo->name_ = name_;
277 displayInfo->SetDisplayId(id_);
278 displayInfo->SetWidth(width_);
279 displayInfo->SetHeight(height_);
280 displayInfo->SetRefreshRate(refreshRate_);
281 displayInfo->SetScreenId(screenId_);
282 displayInfo->SetScreenGroupId(screenGroupId_);
283 displayInfo->SetVirtualPixelRatio(virtualPixelRatio_);
284 displayInfo->SetXDpi(xDpi_);
285 displayInfo->SetYDpi(yDpi_);
286 displayInfo->SetDpi(virtualPixelRatio_ * DOT_PER_INCH);
287 displayInfo->SetRotation(rotation_);
288 displayInfo->SetOrientation(orientation_);
289 displayInfo->SetOffsetX(offsetX_);
290 displayInfo->SetOffsetY(offsetY_);
291 displayInfo->displayState_ = displayState_;
292 displayInfo->SetWaterfallDisplayCompressionStatus(waterfallDisplayCompressionStatus_);
293 displayInfo->SetDisplayOrientation(displayOrientation_);
294 displayInfo->SetIsDefaultVertical(isDefaultVertical_);
295 if (id_ == DEFAULT_DISPLAY_ID) {
296 displayInfo->SetDisplaySourceMode(DisplaySourceMode::MAIN);
297 } else {
298 displayInfo->SetDisplaySourceMode(DisplaySourceMode::NONE);
299 }
300 return displayInfo;
301 }
302 } // namespace OHOS::Rosen